This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Error "weak declaration must be public" with C++ const


OK, I've submitted #83271 on this [1].

Thanks for the standard reference, it turns out I've been looking into
the wrong chapter.

Alexey


[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83271

On Mon, Dec 4, 2017 at 5:02 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 3 December 2017 at 21:36, Alexey Salmin wrote:
>> Hello!
>>
>> I'm a bit puzzled with the g++ behavior which looks inconsistent.
>> Consider the following C++ code:
>>
>> extern const int x; // typically comes from a header file
>> const int x = 0;
>>
>> It produces a global symbol with g++ even though in C++ "const" on
>> variables implies "static". The definition inherits the "extern"
>> specifier from the declaration. So far so good.
>
> Right, it only implies static if it hasn't been explicitly declared with extern.
>
>> Now if you need to provide a weak definition it won't compile:
>>
>> extern const int x;
>> const int __attribute__((weak)) x = 0;
>>
>> error: weak declaration of ‘x’ must be public
>>
>> Adding "extern" to the second line fixes it. It's not clear why g++
>> considers the definition to be public in the first case (strong def)
>> and private in the second (weak def). Both cases work fine in clang++.
>>
>> Is it a bug in g++?
>
> Yes, I think so.
>
>> Another question: even with a strong symbol, it's not completely clear
>> whether omitting "extern" on the second line produces a valid C++ code
>> (it certainly does for plain C). Standard states that using "extern"
>> and "static" in different declarations of the same symbol is an error.
>> However, there's no mention of "const" in that section, so I'm not
>> sure how these two work together.
>
> The standard is clear, see [basic.link]
>
> "A name having namespace scope (6.3.6) has internal linkage if it is
> the name of [...] a non-inline variable of non-volatile
> const-qualified type that is neither explicitly declared extern nor
> previously declared to have external linkage; or [...]"
>
> It has been previously declared extern, so it doesn't have internal linkage.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]