При попытке скомпилировать следующий (упрощенный) код для нескольких платформ, я обнаружил, что он не работает на некоторых, а именно в IBM xlC_r. Дальнейшее расследование показало, что оно также терпит неудачу при приходе и звонках. Он успешно компилируется с g++ и Solaris CC.
Вот код:
int main()
{
int a1[1];
bool a2[1];
for (int *it = a1, *end = a1+1; it != end; ++it) {
//...
bool *jt = a2, *end = a2+1;
//...
}
}
Ошибка xlC_r:
"main.cpp", line 8.25: 1540-0400 (S) "end" has a conflicting declaration.
"main.cpp", line 6.25: 1540-0425 (I) "end" is defined on line 6 of "main.cpp".
ошибка clang:
main.cpp:8:25: error: redefinition of 'end' with a different type
bool *jt = a2, *end = a2+1;
^
main.cpp:6:25: note: previous definition is here
for (int *it = a1, *end = a1+1; it != end; ++it) {
^
Ошибка при запуске:
"ComeauTest.c", line 8: error: "end", declared in for-loop initialization, may not
be redeclared in this scope
bool *jt = a2, *end = a2+1;
^
Вопрос в том, почему это ошибка?
Просматривая стандарт 2003 года, он говорит следующее (6.5.3):
The for statement
for ( for-init-statement; condition; expression ) statement
is equivalent to
{
for-init-statement;
while ( condition ) {
statement;
expression;
}
}
except that names declared in the for-init-statement are in the same
declarative-region as those declared in condition
Здесь нет имен, объявленных в состоянии.
Далее, в нем говорится (6.5.1):
When the condition of a while statement is a declaration, the scope
of the variable that is declared extends from its point of declaration
(3.3.1) to the end of the while statement. A while statement of the form
while (T t = x) statement
is equivalent to
label:
{
T t = x;
if (t) {
statement;
goto label;
}
}
Опять же, я не уверен, что это актуально, поскольку в этом состоянии нет объявления. Поэтому, учитывая эквивалентную переписывание из 6.5.3, мой код должен быть таким же, как:
int main()
{
int a1[1];
bool a2[1];
{
int *it = a1, *end = a1+1;
while (it != end) {
//...
bool *jt = a2, *end = a2+1;
//...
++it;
}
}
}
Который, очевидно, позволил бы вернуться к завершению.