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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx> 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 of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux