Почему auto a=1; компилируется в C?


код:

int main(void)
{
    auto a=1;
    return 0;
}

компилируется без ошибок компилятором MS Visual Studio 2012, когда файл имеет значение .c расширением. Я всегда думал, что когда вы используете .расширения c, компиляция должна быть в соответствии с синтаксисом C, а не c++. Более того, насколько я знаю, авто без типа допускается только в C++ начиная с C++11, где это означает, что тип выводится из инициализатора.

значит ли это, что мой компилятор не торчит на C, или код на самом деле правильный на C-языке?

7   122   2014-05-01 14:50:20

7 ответов:

auto - это старое ключевое слово C, которое означает "локальная область". auto a это то же самое, что auto int a, и поскольку локальная область является значением по умолчанию для переменной, объявленной внутри функции, она также совпадает с int a в этом примере.

это ключевое слово на самом деле осталось от предшественника C B, где не было базовых типов: все было int указатель на int, массив int.( * ) Объявления будут либо auto или extrn [sic]. C унаследовал "все есть int " как правило по умолчанию, так что вы можете объявить целые числа с

auto a;
extern b;
static c;

ISO C избавился от этого, но многие компиляторы по-прежнему принимают его для обратной совместимости. Если это кажется незнакомым, то вы должны понимать, что связанное правило работает в

unsigned d;  // actually unsigned int

который все еще распространен в современном коде.

C++11 повторно использовал ключевое слово, которое мало кто из программистов C++ использовал с исходным значением, для его вывода типа. Это в основном безопасно, потому что "все есть int" правило из C уже было отброшено в C++98; единственное, что ломается, это auto T a, который никто не использовал в любом случае. (Где-то в его труды по истории языка комментарии Страуструп об этом, но я не могу найти точную ссылку прямо сейчас.)

(*) обработка строк в B была интересной: вы бы использовали массивы int и упаковать несколько символов в каждом члене. B был на самом деле нуждающийся в представлении С другой синтаксис.

это и ответ, и расширенный комментарий к нет, это не законно C 1999 года. Ни один приличный современный компилятор C не позволяет.

да auto a=1; является незаконным в C1999 (а также C2011). Просто потому, что это теперь незаконно, не означает, что современный компилятор C должен отклонять код, содержащий такие конструкции. Я бы сказал с точностью до наоборот, что приличный современный компилятор C все еще должен учитывать это.

и clang и gcc делают именно это, когда компиляция примера кода в вопросе по сравнению с версиями стандарта 1999 или 2011 годов. Оба компилятора выдают диагностику, а затем продолжают, как если бы нежелательное утверждение было auto int a=1;.

на мой взгляд, это то, что должен делать приличный компилятор. Путем выдавать диагностику, clang и gcc вполне уступчивы с стандартом. Стандарт не говорит, что компилятор должен отклонить незаконный код. Стандарт просто говорит, что соответствующая реализация должна производить по крайней мере одно диагностическое сообщение, если единица перевода содержит нарушение какого-либо синтаксического правила или ограничения (5.1.1.3).

учитывая код, который содержит незаконные конструкции, любой приличный компилятор попытается разобраться в незаконном коде, чтобы компилятор мог найти следующую ошибку в коде. Компилятор, который останавливается при первой ошибке, не очень хороший компилятор. Есть способ сделать смысл из auto a=1, который должен применить правило "неявного int". Это правило заставляет компилятор интерпретировать auto a=1 как будто auto int a=1 когда компилятор используется в режиме C90 или K&R.

большинство компиляторов обычно отклоняют код (отклонение: отказ от создания объектного файла или исполняемого файла), который содержит недопустимый синтаксис. Это тот случай, когда авторы компилятора решили, что отказ от компиляции не является лучшим вариантом. Самое лучшее, что нужно сделать, это провести диагностику, исправить код и продолжить. Там просто слишком много устаревшего кода, который пересыпан конструкциями, такими как register a=1;. Компилятор должен быть в состоянии скомпилировать этот код в режиме C99 или C11 (с диагностикой, конечно).

auto имеет смысл в C и C++ до стандарта 2011. Это означает, что переменная имеет автоматическое время жизни, то есть время жизни определяется областью. Это противоречит, например,static жизни, где переменная длится "вечно", независимо от объема. auto время жизни по умолчанию, и почти никогда прямо не прописано. Вот почему было безопасно изменить значение в C++.

сейчас C до 99 Стандартный, если вы не укажете тип переменной, она по умолчанию будет int.

так и с auto a = 1; вы объявляете (и определяете)int переменная, время жизни которой определяется областью видимости.

("время жизни "более правильно называется" продолжительность хранения", но я думаю, что это, возможно, менее ясно).

в C и исторических диалектах C++,auto это ключевое слово означает, что a имеет автоматическое хранение. Поскольку он может применяться только к локальным переменным, которые по умолчанию являются автоматическими, никто его не использует; именно поэтому C++ теперь перепрофилировал ключевое слово.

исторически, C разрешил объявления переменных без спецификатора типа; Тип по умолчанию int. Таким образом, это объявление эквивалентно

int a=1;

Я думаю, что это устарело (и, возможно, запрещено) в современном C; но некоторые популярные компиляторы по умолчанию используют C90 (что, я думаю, позволяет это) и, к сожалению, только включают предупреждения, если вы специально их просите. Компиляция с GCC и либо указание C99 с -std=c99, или включение предупреждения с помощью -Wall или -Wimplicit-int, дает предупреждение:

warning: type defaults to ‘int’ in declaration of ‘a’

В C,auto означает то же самое register в C++11: это означает, что переменная имеет автоматическая длительность хранения.

и в C до C99 (и компилятор Microsoft не поддерживает ни C99, ни C11, хотя он может поддерживать его части), тип может быть опущен во многих случаях, когда он будет по умолчанию int.

он вообще не принимает тип от инициализатора. Вы просто случайно выбрали инициализатор, который совместим.

тип компиляции Visual studio доступен по адресу right click on file -> Properties -> C/C++ -> Advanced -> Compile As. Чтобы убедиться, что он скомпилирован как C force .Тогда в этом случае это то, что сказал larsmans (старый с auto ключевое слово). Он может быть скомпилирован как C++ и не знаю.

класс хранения определяет область (видимость) и время жизни переменных и/или функций в программе на языке C.

есть следующие классы хранения, которые могут быть использованы в программе C

auto
register
static
extern

auto класс хранения по умолчанию для всех локальных переменных.

{
        int Count;
        auto int Month;
}

в приведенном выше примере определяются две переменные с одним и тем же классом хранения. авто может использоваться только внутри функций, т. е. локальных переменных.

int это типа по умолчанию ибо auto в ниже код:

auto Month;
/* Equals to */
int Month;

ниже код является законным тоже:

/* Default-int */
main()
{
    reurn 0;
}