Я получаю:
a.c:9: error: ‘foo’ redeclared as different kind of symbol
a.c:6: note: previous declaration of ‘foo’ was here
Я очень сомневаюсь, что это законно.Вы можете устранить неоднозначность foo = &foo_global
, потому что вы не можете «перезаписать» функцию, но void *var = foo
будет неоднозначным (это foo
указатель функции или указатель struct foo_struct
?).
Теперь стандарт:
6.2.1 §2 Для каждого отдельного объекта, который обозначает идентификатор, идентификатор является видимым (т.е. может использоваться) только в пределах области текста программы, называемой ее областью действия.Различные объекты, обозначенные одним и тем же идентификатором, имеют разные области действия или находятся в разных пространствах имен.[...]
Таким образом, идентификаторы должны иметь разные области действия или разные пространства имен.
6.2.1 §4 Если описатель или спецификатор типа, который объявляет идентификаторпоявляется вне любого блока или списка параметров, у идентификатора есть область файла, которая заканчивается в конце единицы перевода.[...]
6.2.1. §6 Два идентификатора имеют одинаковую область действия тогда и только тогда, когда их области действия заканчиваются в одной и той же точке.
Они указывают, что оба идентификатора имеют одинаковыеобласть действия (область действия файла), которая заканчивается в конце блока перевода.
6.2.3 §1 [...] [T] здесь являются отдельными пространствами имен для различных категорий идентификаторов, так какследует:
label names
[...]
tags
структур, объединений и перечислений [...]
members
структур или объединений [...]
всех других идентификаторов, называемых обычными идентификаторами (объявленными в обычных деклараторах иликак константы перечисления).
Пространства имен одинаковы, поскольку оба являются обычными идентификаторами.
Следовательно, они имеют одинаковую область видимости и одно и то же имяпространство, которое не удовлетворяет 6.2.1 § 2.