С++ Предупреждение: анонимный тип без привязки, используемый для объявления переменной

Я вижу это предупреждение при компиляции (gcc 4.6.3, ubuntu):

struct {
} a;

int main() 
{
}


warning: anonymous type with no linkage used to declare variable ‘<anonymous struct> a’ with linkage [enabled by default].

GCC не дает этого предупреждения. Только g++ делает.

Добавление static устраняет предупреждение:

static struct {
} a;

Я не мог понять, что это значит, особенно почему type связан с linkage. Я думал, что связь зависит от того, где и как объявляется переменная, но не от типа самой переменной.

Ответ 1

Это означает, что переменная a имеет связь, например, может быть видна в других единицах перевода. Однако его анонимный тип имеет только внутреннюю связь (нет [external] linkage), поэтому вы не можете фактически получить доступ к переменной a в любой другой единицы перевода, так как вы не можете получить доступ к ее типу.

Создание переменной static даст ей внутреннюю связь, и поэтому ни тип, ни переменная не будут видны в других единицах перевода.

Я не уверен, что (без доступа к компилятору проверять), если анонимное пространство имен будет служить той же цели в этом сценарии.

Ответ 2

Ошибка заключается в том, что вы объявляете переменную a, которая имеет анонимный тип (без имени типа после структуры). Я предполагаю, что это предупреждение, потому что вы не можете снова объявить переменную этого типа (без использования decltype). Я предполагаю, что g++ дает предупреждение, а не gcc, потому что С++ имеет тенденцию быть более строгим языком. Я также тестировал его с помощью clang++ и clang, и они не выдают никаких предупреждений даже с -Wall.

Я бы предположил, что static избавляется от предупреждения, потому что его можно использовать только в одном файле (что означает отсутствие внешней привязки), было бы трудно использовать a в другом файле, потому что вы не знали бы его типа или иметь доступ к нему.

РЕДАКТИРОВАТЬ: К сожалению, в соответствии с ссылкой предупреждение является действительно ошибкой (как бы незначительной) и не было исправлена.