Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const and weak attribute with c++ code

Tags:

c++

c

I am not able to understand the compilation errors below.

First file is a header, test_weak.h:

#ifndef TEST_WEAK_H
#define TEST_WEAK_H
    #ifndef __ASSEMBLER__
const char* const TUTU __attribute__((weak)) ="TUTU";
const char* TUTU_DATE __attribute__((weak)) = __DATE__;
const char* const tutu ="tutu";
    #endif /*ASSEMBLER*/
#endif /*TEST_WEAK_H*/

Second file is the main test.cpp:

int main ()
{
  return 42;
}

To compile I run: g++ -include test_weak.h test.cpp -o test

Compilation result is :

 In file included from <command-line>:0:0:
./test_weak.h:5:44: error: weak declaration of ‘TUTU’ must be public

I am able to run successfully this code by replacing cpp extension by c extension on test source file and using gcc instead of g++. I am also able to fix this error by removing the weak attribute or removing the second const. So yeah I am able to fix the compilation error but no to able to understand the reason of the problem here.

For example this line compile without trouble:

const char* TUTU __attribute__((weak)) ="TUTU";

Why I cannot use a const char* const + weak attribute with c++ ?

like image 408
ArthurLambert Avatar asked Oct 21 '13 10:10

ArthurLambert


2 Answers

The weak attribute tells the linker how to handle multiple definitions of the same entity in different translation units. In C++, for it to be relevant, the entity must have external linkage—that's what the linker means by "public". In C++, a variable which is itself const has internal linkage by default. What you probably want is:

extern char const* const TUTU __attribute__((weak)) = "TUTU";

Formally, this would be undefined behavior in C++ (without the __attribute__, which isn't C++). The purpose of the weak attribute is to allow it, with all instances sharing the same memory (and it will result in undefined behavior, or at least unspecified, if any of the instances have a different initializer.

Actually: what you probably want is:

extern char const TUTU[] __attribute__((weak)) = "TUTU";

No point in introducing the pointer for nothing.

EDIT:

Note that this is one of the differences between C and C++. In C, the const has no impact on linkage.

like image 135
James Kanze Avatar answered Nov 20 '22 17:11

James Kanze


In C++, a variable which is declared const and not explicitly declared extern receives internal linkage (that is, as if it was declared static). Apparently this cannot be combined with the weak attribute.

C doesn't have this rule, so the symbol gets external linkage and thus the attribute can be applied to it when you compile this as C code.

like image 5
Angew is no longer proud of SO Avatar answered Nov 20 '22 18:11

Angew is no longer proud of SO