Переопределение переменных цикла в старых g++

При беге 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, В ответе /questions/25420917/pereopredelenie-peremennoj-v-tsikle-for-v-c/25420934#25420934 цитируется стандарт C++11 по этому вопросу:

6.4 / 2 Правила для условий применяются как к операторам выбора, так и к операторам for и while

6.4/3 Если имя повторно объявлено в самом внешнем блоке подсостояния, контролируемого условием, то объявление, которое повторно объявляет имя, является некорректным.

6.5.3 / 1 имена, объявленные в выражении for-init-, находятся в том же декларативном регионе, что и имена, объявленные в условии

Поэтому мне больше не интересно, почему это нелегальный C++.:-) Я просто хотел бы получить его скомпилировать!

Я посмотрел на опции G++, связанные с языковыми диалектами. Согласно инструкции,

Если -ffor-scope область переменных, объявленная в выражении for-init-Statement, ограничена ‘for’ Сам цикл, как указано в стандарте C++. Если -fno-for-scope указано, что область переменных, объявленная в for-init-инструкции, распространяется до конца включающей области, как это имело место в старых версиях G++ и других (традиционных) реализациях C++.

Это единственный, даже отдаленно связанный вариант звучания, который я смог найти. Как ни странно, мимоходом -fno-for-scope в g++ компилирует пример; без предупреждений даже с -Wall -Wextra, Однако, возвращаясь к коду, который я хотел бы скомпилировать, эта опция генерирует много ошибок, потому что переменные, инициализированные в операторе for-init- теперь, имеют расширенную область действия. Понятно, что это не решение проблемы.

Просто чтобы уточнить: я не собираюсь компилировать код 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 жили в другой области, чем тело цикла или окружающий код?

0 ответов

Другие вопросы по тегам