Компилятор C игнорирует «static» для объявления структуры - PullRequest
0 голосов
/ 30 августа 2018

В C, если я объявлю структуру следующим образом:

static struct thing {
    int number;
};

и скомпилируйте его (в данном случае с gcc), компилятор выводит это предупреждение:

предупреждение: «static» игнорируется в этом объявлении

[- Wmissing-объявления]

Почему это?

Мое намерение сделать статическую структуру будет состоять в том, чтобы не допустить thing в глобальное пространство имен, чтобы другой файл мог объявить свой собственный thing, если он этого хочет.

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

Нельзя определить хранилище, не указав фактический объект.

static struct thing {
    int number;
}obj1,obj2;

в порядке и:

struct thing {
    int number;
};

static struct thing x,y;
0 голосов
/ 30 августа 2018

Теги Struct (и имена typedef) имеют без связи , что означает, что они не являются общими для единиц перевода. Вы можете использовать термин «частный», чтобы описать это. Для двух разных юнитов совершенно нормально определять свои struct thing.

Проблема возникнет только в том случае, если попытаться выполнить перекрестный вызов функции с внешней связью, которая принимает struct thing или тип, полученный из этого. Вы можете минимизировать вероятность этого, гарантируя, что функции с внешней связью вызываются только через прототипы в заголовочных файлах (то есть не используйте локальные прототипы).

0 голосов
/ 30 августа 2018

Вы не можете использовать static таким образом, чтобы управлять связыванием типа, как вы могли бы для функции или объекта, потому что в типах C в любом случае никогда не было связывания.

«Глобальное пространство имен» - это не совсем тот термин, который вам здесь нужен. C описывает имена объектов и функций как имеющие «внешнюю связь», если одно и то же имя может быть объявлено в разных единицах перевода, чтобы означать одно и то же (как значение по умолчанию для функций), «внутренняя связь», если одно и то же имя может быть переопределено в одна и та же единица перевода означает одно и то же (например, объявления, помеченные static) или «отсутствие связи», когда в объявлении именуется другой объект или функция из любого другого объявления (например, переменные, определенные в теле функции). (Единицей перевода, грубо говоря, является один файл * .c вместе с содержимым включаемых в него заголовков.) Но все это не относится к типам.

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

(И только в случае, если пользователь C ++ сталкивается с этими вопросами и ответами, обратите внимание, что правила для этого в C ++ очень разные.)

...