Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.78
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
#1

Циклы for. Проблема объявления/инициализации - C++

31.08.2008, 03:42. Просмотров 4442. Ответов 23
Метки нет (Все метки)

Эх, так и придется создавать новую тему. А то, блин, интересно ж...
Итак, я тут в недавней теме утверждал, что блок инициализации цикла for является внешним по отношению к его внутреннему блоку (блоку команд, то бишь).
CheshireСat's евангелие не соглашается со мной
Цитата Сообщение от CheshireCat Посмотреть сообщение
Сообщение от Vourhey
Просто переменная объявленная в инициализации цикла считается внешней по отношению к самому блоку цикла. То есть, она не внутренняя и не скрытая по отношению ко внешнему от цикла миру.
Гм. Евангелие 14882-2003 (песнь 3.3.2 стих 4) утверждает иное...
и предлагает открыть для этой байды тему. ОК. Открыл.

С чего возник базар? С того, что нужно, все-таки, выяснить чем же особенны такие конструкции (с объявлением переменных в заголовке цикла):
Код
	for (int i = 0; i < 5; i++)
	{
	}
Не долго думая, надо чапать в листинг дизассемблерный. Вся канитель проводилась в VS 2008. Состряпал такой код:
Код
#include <iostream>

using namespace std;

void main()
{
	int i = 1;
	for (int i = 0; i < 10; i++)
	{
	}
}
В листинге видим следующее:
Код
	int i = 1;
0041138E C7 45 F8 01 00 00 00 mov         dword ptr [i],1   инициализируем i
	for (int i = 0; i < 10; i++)
00411395 C7 45 EC 00 00 00 00 mov         dword ptr [i],0   инициализируем i ту, что в заголовке цикла
0041139C EB 09            jmp         main+37h (4113A7h)    проверяем условие выхода из цикла(cmp dword ptr [i],0Ah)
0041139E 8B 45 EC         mov         eax,dword ptr [i]     три следующие команды - инкремент
004113A1 83 C0 01         add         eax,1 
004113A4 89 45 EC         mov         dword ptr [i],eax 
004113A7 83 7D EC 0A      cmp         dword ptr [i],0Ah     проверка условия выхода
004113AB 7D 02            jge         main+3Fh (4113AFh)    уходим из цикла
	{
	}
004113AD EB EF            jmp         main+2Eh (41139Eh)    цикл
Как видно, обе переменные объявлены вне цикла. По байтам команд видно, что цикл работает с последней объявленной "внешней" переменной.
Уберем инициализацию объявление из заголовка.
Код
#include <iostream>

using namespace std;

void main()
{
	int i = 1;
	for (i = 0; i < 10; i++)
	{
	}
}
Дизассемблер скажет следующее:
Код
	int i = 1;
0041138E C7 45 F8 01 00 00 00 mov         dword ptr [i],1 
	for (i = 0; i < 10; i++)
00411395 C7 45 F8 00 00 00 00 mov         dword ptr [i],0 
0041139C EB 09            jmp         main+37h (4113A7h) 
0041139E 8B 45 F8         mov         eax,dword ptr [i] 
004113A1 83 C0 01         add         eax,1 
004113A4 89 45 F8         mov         dword ptr [i],eax 
004113A7 83 7D F8 0A      cmp         dword ptr [i],0Ah 
004113AB 7D 02            jge         main+3Fh (4113AFh) 
	{
	}
004113AD EB EF            jmp         main+2Eh (41139Eh)
Видно, что теперь он работает с единственной внешней переменной i.

Теперь можно провести небольшой эксперимент:
Код
#include <iostream>

using namespace std;

void main()
{
	int i = 1, *j;
	for (i = 0; i < 10; i++)
	{
		j = &i;
	}
	cout<<"J = "<<*j<<"  I = "<<i<<endl;
	cin.get();
}
Из вышенаписанного должно следовать, что внешняя переменная i будет увеличиваться до 10-ти. Соответственно, в j тоже будет десять. Если скомпилить и выполнить, то результат:
J = 10 I = 10.

А теперь засунем новую переменную В БЛОК цикла:
Код
#include <iostream>

using namespace std;

void main()
{
	int i = 1, *j;
	for (i = 0; i < 10; i++)
	{
		int i; i++;
		j = &i;
	}
	cout<<"J = "<<*j<<"  I = "<<i<<endl;
	cin.get();
}
Какой результат? Внутри цикла будет инкрементироваться переменная i десять раз. В итоге у нас получится ожидаемое:
J = 1 I = 10

И последнее:
Код
#include <iostream>

using namespace std;

void main()
{
	int i = 1, *j;
	for (int i = 0; i < 10; i++)
	{
		j = &i;
	}
	cout<<"J = "<<*j<<"  I = "<<i<<endl;
	cin.get();
}
Если я ошибаюсь и int i = 0 у нас происходит внутри блока цикла, то наша переменная i каждую итерацию должна обнуляться... Посмотрим:
J = 10 I = 1

Ах ты батюшки. Не обнулилась. А не сделала она этого потому что объявлена как вне блока цикла. На уровень выше самого блока команд цикла. И в исполнении цикла строка int i = 0 никакого участия не принимает. Абсолютно.
Если совсем скучно, то можно заглянуть в "Бархатный путь С++":
Дело в том, что тело оператора цикла for (оператор или блок операторов) имеет ограниченную область действия имён. А область действия имени, объявленного в операторе-инициализаторе, оказывается шире этой области.

Заголовок цикла for в C++ - центр управления циклом. Здесь следят за внешним миром, за тем, что происходит вне цикла. И потому все обращения к переменным и даже их новые объявления в заголовке цикла относятся к "внешней" области видимости. Следствием такого допущения (его преимущества далеко не очевидны) является правило соотнесения имени, объявленного в заголовке и области его действия.

По отношению к объявлению переменной в заголовке оператора цикла for, правило соотнесения гласит, что область действия имени, объявленного в операторе инициализации цикла for, располагается в блоке, содержащем данный оператор цикла for.
Вообщем, при должной сноровке и "удаче" можно огрести. Очень редко, но можно. Главное знать, что все, что происходит в заголовке цикла (в области инициализации) - это вне зоны действия его блока. И все эти действия не принимают участия в исполнении операторов цикла.

Дабы, это выглядело, как настоящая тема, вопрос: Где я ошибся? Кто, что думает по этому поводу? Может, в объявлении/инициализации в заголовке цикла нет ничего, на что стоило бы обращать внимание?

P. S. вот именно, блин, поэтому такое использование может принести сюрпризы (это ж какую конструкцию надо придумать), если не знать, как оно работает. Я не утверждаю, что так делать нельзя, или плохо. Так делать можно. Ничего страшного в этом нет абсолютно. Просто надо иметь ввиду.

P. P. S. CheshireСat, что на это скажет твое евангелие?

Добавлено через 28 минут 25 секунд
Кстати, как мне сразу в голову не пришло. Если мы уберем int i; внешний и оставим только в заголовке то:
Код
	for (int i = 0; i < 10;i++)
0041138E C7 45 F8 00 00 00 00 mov         dword ptr [i],0 
00411395 EB 09            jmp         main+30h (4113A0h) 
00411397 8B 45 F8         mov         eax,dword ptr [i] 
0041139A 83 C0 01         add         eax,1 
0041139D 89 45 F8         mov         dword ptr [i],eax 
004113A0 83 7D F8 0A      cmp         dword ptr [i],0Ah 
004113A4 7D 02            jge         main+38h (4113A8h) 
	{
	}
004113A6 EB EF            jmp         main+27h (411397h)
Если сравнить со вторым дизассемблерным листингом, то отличий - 0. Только удалилась строка с присваиванием переменной единицы. А так, все абсолютно идентично. Даже адреса те же.
В итоге мы получили ту же внешнюю по отношению к блоку операторов цикла переменную. Даже с аналогичным адресом То есть, на уровне ассемблера код не меняется. Тот же самый листинг получается из:
Код
. . .
int i;
for (i = 0; i < 10;i++)
{
. . .
Это говорит о том, что такие ситуации аффектятся в случае использования нескольких переменных, манипулирования их адресами и именами.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.08.2008, 03:42     Циклы for. Проблема объявления/инициализации
Посмотрите здесь:

Правила объявления инициализации - C++
Напишите основные - самые главные правила обьявления инициализации.

Отличие объявления, определения и инициализации - C++
Здравствуйте, товарищи. Читаю тут книжицу по C++, учусь потихоньку. И возник у меня вопрос нерядового характера: в чём...

объявления - C++
в чем отличие такого определения float var = 1.f; от такого float var = 1.0f;

Объявления массива. - C++
Как увеличить количество переменных в массиве?

Объявления классов - C++
Класс может быть объявлен так: class MyClass { ... }; а может быть объявлен и так typedef class

Ошибки объявления - C++
Stack.h #pragma once class Stack { public: void push (StackPtr *,int); int pop(StackPtr*); int isEmpty(StackPtr);

По поводу объявления - Visual C++
Есть форма. При нажатии на кнопку из текстбокса значение сохраняется в динамические список. Где мне вписать объявление списка и его...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Spo1ler
292 / 52 / 3
Регистрация: 22.05.2008
Сообщений: 788
31.08.2008, 12:40     Циклы for. Проблема объявления/инициализации #2
+1 за полезную тему. довольно интересный материал
ЗЫ дисассемблирование рулит
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,352
31.08.2008, 15:21     Циклы for. Проблема объявления/инициализации #3
Спасибо Vourhey за столь любопытное исследование.
Но, у меня вопрос первый: а зачем нам дизассемблирование? Тот код, который мы получаем в дизассемблере, говорит только лишь о том, что вот так вот это реализовано в данном конкретном компиляторе на данной конкретной ОС... и ничего не говорит о том, что произойдет на другом компиляторе и/или другой ОС/железе.

С моей точки зрения, представляют интерес два вопроса:
1. Что говорит Стандарт - т.е., что должно быть?
2. Как реально ведут себя некоторые современные компиляторы, - т.е. насколько точно они соответствуют Стандарту, либо не соответствуют. Что есть на самом деле?

Итак:
1. Стандарт определяет поведение и область видимости управляющей переменной исчерпывающим образом:
[basic.scope.local] 3.3.2 Local scope
....
4 Names declared in the for-init-statement, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement; see 6.4.
То есть, утверждение "То есть, она не внутренняя и не скрытая по отношению ко внешнему от цикла миру." мне представляется неверным. Вероятно, мы Vourhey с разошлись в трактовке этого предложения...
2. Из доступных мне компиляторов: (В последние годы я работаю в основном с Microsoft Visual C++....)
а). MS visual C++ 6.0 (1998) не соответствует Стандарту: область видимости управляющей переменной цикла простирается от заголовка цикла до конца объемлющего блока; т.е., код вида
Код
for(int i = 0; i < SOME_VALUE; ++i)
{
    // ... что-то делаем...
}
// ... еще что-то...
i = 20;
cout << i << endl;
// ...
нормально скомппилируется. Ну что ж, VC++ 6 был выпущен еще примерно за полгода до принятия Стандарта, так что с него взятки гладки...
б). MS Visual C++ 7.0 (2002) и 7.1 (2003) занимают промежуточную позицию: по умолчанию включен старый режим, ключ компилятора /Zc:forScope позволяет включить режим точного соответствия Стандарту.
в). MS Visual C++ 8.0 (2005) и последующие по умолчанию точно соответствуют Стандарту; это означает, что приведенный код просто не скомпилируется. Впрочем, все тот же ключ forScope позволяет обеспечить таки совместимость со старым унаследованным кодом и скомпилировать приведенный фрагмент.
г). GCC 4.2.2 (Linux) точно соответствует Стандарту.
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
31.08.2008, 15:28  [ТС]     Циклы for. Проблема объявления/инициализации #4
Стоп, стоп, стоп. Я не слова не сказал про область видимости переменной. Заметь.
Я объяснил, что не так с этим объявлением. По-моему, вполне доступно. С учетом того, что компилеров куча и настроить их можно по-разному код нужно писать безопаснее. А объявление в заголовке цикла это сделать не позволяет на 100%. Что и требовалось доказать. Такое написание вполне нормально, но есть и свои минусы.

P. S. мне особо без разницы, что где написано, пока я не увижу. Дизассемблерный листинг показывает лучше всего.

P. P. S. ты можешь компилить в студии, а я, например, в G++ (версия 3.1) могу скомпилить такой код:
Код
   for(int i = 0;i<10;i++)
   {
      int i;
   }
надеюсь ты понимаешь, что если бы int i = 0 ,имела внутреннюю область видимости, то этот код бы не компилился с ошибкой redeclaration of "i". Возможность компиляции такой записи говорит сама за себя. Тут даже на уровне с++ переменная внешняя.

Повторюсь. Я не говорю, что это неправильно и так нельзя делать. Это нормально, и так вполне нормально кодить. Просто в жизни все бывает. И полностью рабочий код в одном случае может сработать не так, как хотелось в другом. Надо это учитывать.
Так что, будем объективны. Код нужно писать безопасней, если возможно.
qwone
8 / 8 / 1
Регистрация: 18.08.2008
Сообщений: 129
31.08.2008, 23:06     Циклы for. Проблема объявления/инициализации #5
Код
for(int i = 0;i<10;i++)
   {
   }
for([COLOR=Red]int i = 0[/COLOR];i<10;i++)
   {
   }
for([COLOR=Red]int i = 0[/COLOR];i<10;i++)
   {
   }
Да я об этом приколе знаю .Вот из-за этого у меня не получается компилить. переопределение переменной i.
Код
int i;
for( i = 0;i<10;i++)
   {
   }
for( i = 0;i<10;i++)
   {
   }
for( i = 0;i<10;i++)
   {
   }
так лучше .
Вот еще интересно , а если в цикле цикл.
Код
int i;
for( i = 0;i<10;i++){ for(int j = 0;j<10;j++)[{
       }
    }
for( i = 0;i<10;i++){ for(int j = 0;j<10;j++)[{
       }
    }
for( i = 0;i<10;i++){ for(int j = 0;j<10;j++)[{
       }
    }
для j скорее всего переопределение не будет .
Spo1ler
292 / 52 / 3
Регистрация: 22.05.2008
Сообщений: 788
31.08.2008, 23:20     Циклы for. Проблема объявления/инициализации #6
почему скорее всего? почему не проверили? эх.... наверное придется мне разбираться с линуксовыми дизасемблерами
и что ето за скобки квадратные такие?
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
31.08.2008, 23:35  [ТС]     Циклы for. Проблема объявления/инициализации #7
Примеров можно кучу придумать, мне влом их в gdb загонять
Главное, подтверждается то, что такое использование в редких случаях, но все же может быть неоднозначным. Что может вызвать трудности.
Spo1ler
292 / 52 / 3
Регистрация: 22.05.2008
Сообщений: 788
31.08.2008, 23:42     Циклы for. Проблема объявления/инициализации #8
зачем gdb? gcc\g++ с ключом -S рулет
upd извиняюсь, тут немного не то
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,352
01.09.2008, 12:09     Циклы for. Проблема объявления/инициализации #9
Цитата Сообщение от Vourhey Посмотреть сообщение
Стоп, стоп, стоп. Я не слова не сказал про область видимости переменной. Заметь.
Хотел бы заметить, но - не получается... Приведенная цитата: "То есть, она не внутренняя и не скрытая по отношению ко внешнему от цикла миру." - для меня есть ни что иное, как утверждение именно об области видимости переменной. Разве не так?

Далее. Если приведенный пример кода компилируется в g++ (а он действительно компилируется!), то я не вполне понимаю, почему. Поскольку таким образом g++ нарушает требования п.6.5.3 clause 3 Стандарта. Кстати, ни MSVC++ 8.0, ни Comeau, ни компилятор Interstron - этот код не компилируют.

Конечно же, код нужно писать безопасным. Но - с моей точки зрения (IMHO - имею мнение, хрен оспоришь!) код нужно писать прежде всего по Стандарту. А если какой-то компилятор отклоняется от Стандарта.... что ж, очень плохо, - либо нужно менять компилятор, либо изобретать костыли и подпорки; и, разумеется, не забыть эти костыли прокомментировать!
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
01.09.2008, 13:14  [ТС]     Циклы for. Проблема объявления/инициализации #10
"То есть, она не внутренняя и не скрытая по отношению ко внешнему от цикла миру." - для меня есть ни что иное, как утверждение именно об области видимости переменной. Разве не так?
Не так.
Таким же макаром. Пусть не скомпилируют, а шестой билдер и g++ скомпилируют.
А то что, на более низком уровне:
Код
int i;
for(i = 0; i<9;. . .
и
Код
for(int i = 0; i< 9;. . .
аналогичны, я пояснил выше. К чему это?
К тому, что написав так:
Код
int i;
for(i = 0; i<9;. . .
я точно знаю область видимости своей переменной на любом компилере, с любыми аргументами. А вот второй пример вносит неоднозначность при переносе и перекомпилировании. Вот и безопасность.

Пиши по стандарту. Стандарты есть везде. А еще есть реальность...

P. S. VC++ поддерживает стандарты какие-то еще ? Батюшки...новости... У мелкомягких вообще нет никаких стандартов. Они сами себе стандрат

P. P. S. Те, кто считают, что у С++ есть общий на всех, признанный стандарт ошибаются. Его нет. Есть даже разные редакции стандартов. Так что говорить, что один компилирует правильно, другой нет - необдуманно. Надо кодить обдуманно, чтобы избежать подводных камней. А не идти тупо напролом с одной редакцией одного из стандартов...
Sined
9 / 7 / 2
Регистрация: 30.08.2008
Сообщений: 120
03.09.2008, 03:52     Циклы for. Проблема объявления/инициализации #11
Цитата Сообщение от Vourhey Посмотреть сообщение
Не так.
Таким же макаром. Пусть не скомпилируют, а шестой билдер и g++ скомпилируют.
А то что, на более низком уровне:
Код
int i;
for(i = 0; i<9;. . .
и
Код
for(int i = 0; i< 9;. . .
аналогичны, я пояснил выше. К чему это?
Нет уж, они не аналогичны, так как прокомпелировав в Visual Studio 6, и в Visual Studio 2005-2008 они будут разными. Сам пробовал!!!

Прокомпелировав этот код:

Код
for(int i=0;i<10;i++)
{
}
int i=2;
то будет ошибка redeclaration of "i" в Visual Studio 6, а в Visual Studio 2005-2008 нет!!!

а qwone все-таки пишет на Visual Studio 6 как раз там та такая ошибка и будет, и опять повторяю, что в Visual Studio 2005-2008 нет!!!
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
03.09.2008, 11:53  [ТС]     Циклы for. Проблема объявления/инициализации #12
Sined, "сам пробовал" - не аргумент. Приведи дизассемблерный листинг, чтобы доказать, что разные вещи получатся на низком уровне. Тогда поверю. Это раз.

Два. У меня наоборот на 2008 не компилится, а в билдере и g++ легко.

P. S. твои споры еще раз доказывают, что стандарта С++ единого нет.
Sined
9 / 7 / 2
Регистрация: 30.08.2008
Сообщений: 120
03.09.2008, 12:22     Циклы for. Проблема объявления/инициализации #13
Нет, подожди, подожди, ты пишеш, что компилирование происходит в Visual Studio 2008, вот приме твоего описания:

Цитата Сообщение от Vourhey Посмотреть сообщение
Не долго думая, надо чапать в листинг дизассемблерный. Вся канитель проводилась в VS 2008. Состряпал такой код:

Код
#include <iostream>

using namespace std;

void main()
{
	int i = 1;
	for (int i = 0; i < 10; i++)
	{
	}
}
В листинге видим следующее:...
А теперь ты пишешь что "У меня наоборот на 2008 не компилится, а в билдере и g++ легко." так как компилируеться или нет?!
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
03.09.2008, 12:35  [ТС]     Циклы for. Проблема объявления/инициализации #14
Вот блин, а...
Я же написал, что
Код
for(int i;...
{
   int i;
Запросто скомпилится в g++ (и в билдере). Но не скомпилится под VS2008 (без определенных параметров).
Блин, как я по-твоему листинг дизассемблерный приводил, если код выше (в твоем сообщении) не компилится?! Сам, что ли, писал?

P. S. понимаешь ли...кроме компилеров cl.exe есть еще много...
Sined
9 / 7 / 2
Регистрация: 30.08.2008
Сообщений: 120
03.09.2008, 13:25     Циклы for. Проблема объявления/инициализации #15
Я написал, что не компилируется в Visual Studio 6 (шестая версия) а в Visual Studio 2005
компилируется, а за Visual Studio 2008 тебе нечего сказать не могу так как его у меня нет.

Но я не думаю, что в 2005 и 2008 будут такие различия. "Но" это не довод но всетаки в Visual Studio 6 и в Visual Studio 2005 есть.
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
03.09.2008, 13:25  [ТС]     Циклы for. Проблема объявления/инициализации #16
Что там есть?

Я не пойму, че ты доказать хочешь, но не можешь...
Sined
9 / 7 / 2
Регистрация: 30.08.2008
Сообщений: 120
03.09.2008, 13:47     Циклы for. Проблема объявления/инициализации #17
Почему сразу хочу, но не могу.
Ты пишешь по первому листингу дизасемблера, что две переменные являються вне цыкла.

А ты попробуй такой код:

Код
void main()
{
	for(int i=0;i<5;i++)
	{
	}
	printf("%d",i);               [B][COLOR="Red"]//ошибка error C2065: 'i' : undeclared identifier
					//так как инициалезация переменной происходит
 					//внутри блока for[/COLOR][/B]
}
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,352
03.09.2008, 13:49     Циклы for. Проблема объявления/инициализации #18
Цитата Сообщение от Vourhey Посмотреть сообщение
Два. У меня наоборот на 2008 не компилится, а в билдере и g++ легко.
P. S. твои споры еще раз доказывают, что стандарта С++ единого нет.
А не путаешь ли ты две разные вещи:
1. существование Стандарта языка как регламентирующего документа - как должно быть,
2. различные реализации этого Стандарта независимыми производителями компиляторов, - что есть на самом деле?

Реализации могут отклоняться от требований Стандарта; насколько мне известно, нет ни одного компилятора, на все 100% соответствующего Стандарту.
Sined
9 / 7 / 2
Регистрация: 30.08.2008
Сообщений: 120
03.09.2008, 14:00     Циклы for. Проблема объявления/инициализации #19
Цитата Сообщение от CheshireCat Посмотреть сообщение
2. различные реализации этого Стандарта независимыми производителями компиляторов, - что есть на самом деле?

Так его, так...
Потому как Произвидитель Visual Studio 6 и Visual Studio 2005 один и тот-же, а стандарта нет.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.09.2008, 14:09     Циклы for. Проблема объявления/инициализации
Еще ссылки по теме:

объявления друг в друге - C++
как это переделать чтобы работало typedef struct _Info { _proc CallBack; }*_pInfo; typedef _pInfo(*_proc)(); не...

Порядок объявления библиотек? - C++
Начал изучать С++ и столкнулся с такой проблемой: в книгах пишут, что при использовании класса string его надо явно объявлять, но у меня...

Место объявления функции - C++
Не могу сообразить, как определить такой конструктор в структуре(классе) struct Sales_data { string bookNo; unsigned units_sold =...

Синтакасис объявления функций - C++
... double func(double x, double a); int main(int argc, char *argv) ... double func - вещественный тип данных, если не ошибаюсь....

Различие объявления строк - C++
Изучая указатели, дошел до использования в строках. Все было понятно, за исключением нескольких фрагментов кода: Целый код для...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
03.09.2008, 14:09  [ТС]     Циклы for. Проблема объявления/инициализации #20
Цитата Сообщение от Sined Посмотреть сообщение
Почему сразу хочу, но не могу.
Ты пишешь по первому листингу дизасемблера, что две переменные являються вне цыкла.

А ты попробуй такой код:

Код
void main()
{
    for(int i=0;i<5;i++)
    {
    }
    printf("%d",i);               [B][COLOR=Red]//ошибка error C2065: 'i' : undeclared identifier
                    //так как инициалезация переменной происходит
                     //внутри блока for[/COLOR][/B]
}
О боже. Я молчу. Может, тебе выспаться? Читай внимательней выше. Я свое время, на тех, кто не читает, растрачивать не собираюсь.

CheshireCat, нет, я не путаю эти вещи. Единого стандарта С++ нет. Параллельно существуют несколько стандартов. Да короче, че я тут с тобой спорю... Даже, если бы и был, то практика уже все показала и подтвердила, что толку от них. Но его нет.
Есть, например: iso14882:2003/1998. Они существуют параллельно. Я молчу про различные их редакции.
Если ни один компилер на 100% не поддерживает ни один стандарт, то тем более, этот код становится менее безопасным.

Добавлено через 2 минуты 16 секунд
Sined, вот именно, что если нет стандарта единого, этор еще больше уменьшает безопасность приведенного мною кода. Короче, ты тут споришь, а сам ни одного аргумента не привел.
Хочешь настоящий стандарт увидеть? Иди и учи ada. Тогда с тобой поговорим. И ассемблер заодно...
Ты, по-моему, в бронепоезде сидишь...

g++ даже ошибку покажет умнее:
error: name lookup of `i' changed for new ISO `for' scoping
Эх, Sined, если ты на одной студии все гоняешь, то, навряд ли, можешь что-то новое мне открыть
Еще раз повторю, что откомпилированный:
Код
for(int i=1;i<5;i++)
{
      int i = 5;
}
говорит, что это и не внутренняя переменная.

Сейчас основные два стандарта поддерживаются. Никто не отменял ничего.

Так что, "написание по стандарту" в данном случае есть фигня. Так как, и та и эта запись идут по стандарту. Просто в одном случае я буду писать, если знаю, что никому не буду давать свой код, не буду его портировать. В противном случае (если я знаю, что придется портировать, разными компилерами компилить, на разных системах тестить), то мой мозг будет знать, что для данной ситуации, лучше объявить переменную вне цикла. Так я гарантированно задам для нее namespace.
Yandex
Объявления
03.09.2008, 14:09     Циклы for. Проблема объявления/инициализации
Закрытая тема Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru