При беге git bisect
в некотором коде C ++ (написанном для GCC) я столкнулся с ошибкой компилятора, сгенерированной чем-то вроде
#include <stdio.h>
int main() {
for (int i = 0; i < 10; ++i) {
long i = 0;
printf("%ld\n", i);
}
return 0;
}
Этот кусок кода, я считаю, совершенно стандартный C99 (gcc -std=c99
компилирует это нормально), однако g++
терпит неудачу из-за переобъявления i
, Ответ https://stackoverflow.com/a/12351531/560450 процитировал стандарт C ++ 11 по этому вопросу:
6.4 / 2 Правила для условий применяются как к операторам выбора, так и к операторам for и while
6.4 / 3 Если имя повторно объявлено во внешнем блоке подстанции, контролируемой условием, то объявление
повторно объявляет, что имя плохо сформировано.6.5.3 / 1 имена, объявленные в выражении for-init-, находятся в том же декларативном регионе, что и имена, объявленные в условии
Поэтому мне больше не интересно, почему это нелегальный C ++. 🙂 Я просто хотел бы получить его скомпилировать!
Я посмотрел на опции G ++, связанные с языковыми диалектами. Согласно руководство,
Если
-ffor-scope
указан диапазон переменных, объявленных в
для сохр-заявление ограничивается‘for’
сам цикл, как указано
по стандарту C ++. Если-fno-for-scope
указан, объем
переменные объявлены в для сохр-заявление распространяется на конец
объем, как это было в старых версиях G ++, и другие
(традиционные) реализации C ++.
Это единственный, даже отдаленно связанный вариант звучания, который я смог найти. Как ни странно, мимоходом -fno-for-scope
в g++
компилирует пример; без предупреждений даже с -Wall -Wextra
, Однако, возвращаясь к коду, который я хотел бы скомпилировать, эта опция генерирует много ошибок, потому что переменные, инициализированные в для сохр-заявление теперь там расширили область. Понятно, что это не решение проблемы.
Просто чтобы уточнить: я не собираюсь компилировать код C99 с помощью компилятора C ++, это было бы глупо. У меня есть немного кода C ++; git blame
говорит, что строка с переопределением относится к 2001 году. Я хотел бы скомпилировать коммит, который был помечен для выпуска в 2011 году, поэтому я полагаю, что он не был прерван в то время.
Что я мог сделать, чтобы получить его без изменений? В настоящее время я выбираю коммит, который переименовывает переменную, но я предпочел бы передать что-то в CXXFLAGS
в configure
, В целом, почему (или сделал) g++
иметь такое поведение с -fno-for-scope
и переопределения?
РЕДАКТИРОВАТЬ: Хорошо, наверное, мне следовало быть более откровенным. Тот факт, что у меня есть некая кодовая форма 2001, которая сегодня не работает, просто для того, чтобы установить некоторый контекст. Современный master
репозитория, конечно, компилируется без какой-либо хитрости компилятора. Тем не менее, меня интересует, как я могу сделать g++
ведут себя так, как вели себя исторически, потому что существует огромная вероятность того, что время коммита было помечено, g++
принял этот вид кода.
EDIT2: После игры с -fdump-tree-original
, вопрос в основном становится: Была ли какая-либо стандартная или нестандартная реализация C ++ (предпочтительно в GCC), в которой переменная, объявленная в for-init-statement
жил в другой области, чем тело цикла или окружающий код?
Задача ещё не решена.
Других решений пока нет …