Что означает «__G»?

#c #gcc #c11 #gcc4.9

#c #gcc #c11 #gcc4.9

Вопрос:

Что __G означает в C?

Я использую GCC 4.9.

Я использую последнюю версию MinGW.

Я компилирую с -std=gnu11 помощью .

У меня есть следующий код C (компилируемый с GCC как C11):

 #ifndef __G
#define __G 0
#endif
  

Он отлично компилируется.

Но теперь, при компиляции с последней версией MinGW, я получаю следующее:

 In file included from ../common/sysbase/sysbase.h:6:0,
             from Monitor.c:5:
../common/sysbase/sysbase_chk.h:3:13: error: expected ';', ',' or ')' before numeric constant
#define __G 0

compilation terminated due to -Wfatal-errors.
  

GCC под MinGW64, похоже, использует `__G для чего-то.

Я не смог найти его ни в одном заголовке.

Комментарии:

1. Это идентификатор. Это тот, который зарезервирован для реализации, поэтому вы не должны использовать его в своем собственном коде; либо компилятор, либо заголовок, являющийся частью стандартной библиотеки, могут свободно определять его для своих собственных целей.

2. Но знаете ли вы, из какого API / стандарта оно взято?

3. Я знаю, что идентификаторы, начинающиеся с «__», должны считаться зарезервированными словами. Но мое использование здесь именно таково! Я создаю API и использую «__G» и «__LE» в качестве макросов для определения способа хранения слов в памяти на целевой машине… Теперь, после более чем года компиляции кодов с этими заголовками, нужно ли мне изменять все мои коды? 🙁

4. Понятия не имею. Вероятно, это не относится ни к какому API или стандарту. Стандарт ISO C гласит, что он зарезервирован для реализации. Не используйте его самостоятельно. Это приводит к тому, что поведение вашей программы не определено. Если это защита включения, я предлагаю использовать что-то вроде #ifndef HEADER_NAME_H

5. «зарезервированные слова» означает зарезервированные для реализации (т. Е. компилятора плюс все остальное, что требуется для реализации стандарта C), а не для себя! Вы должны выбрать соглашение об именовании, которое не перекрывается с зарезервированными идентификаторами; и вам придется сообщить об этом другим пользователям вашего кода.

Ответ №1:

__G это просто идентификатор. Я не знаю о каком-либо стандартном его использовании, но поскольку оно начинается с двух символов подчеркивания, оно зарезервировано для реализации для всех целей. Слово «реализация» здесь относится к компилятору и библиотеке C, а не к любому написанному вами коду (если только вы сами не реализуете часть компилятора или стандартной библиотеки C).

(Стандарт гласит, что любой идентификатор, начинающийся с двух символов подчеркивания или с символа подчеркивания и заглавной буквы, зарезервирован для любого использования; любой идентификатор, начинающийся с символа подчеркивания, зарезервирован для использования с областью действия файла. См. Раздел 7.1.3 проекта стандарта C N1570.)

Вы не должны использовать его в своем собственном коде. Это приводит к тому, что поведение вашей программы не определено.

Реализации C (будь то компилятор, компоновщик, заголовок или библиотека) разрешено определять __G любым удобным для нее способом. По-видимому, это то, с чем вы столкнулись.

В ответ на вопрос в вашем комментарии:

Теперь, после более чем года компиляции кодов с этими заголовками, нужно ли мне изменять все мои коды?

Да, это именно то, что я говорю. Ваше использование __G всегда было неправильным; вы просто не сталкивались с какими-либо видимыми симптомами до сих пор.

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

Комментарии:

1. Можно добавить, что _G это будет одинаково зарезервировано, поскольку оно начинается с подчеркивания и заглавной буквы.