const has internal linkage in C++??

Q

qazmlp

const has internal linkage in C++, but external linkage in C.
Am I right ?

But, linker reports multiply-defined error if the
following header is included in multiple .cpp files.


// test_const.h
#ifndef HEADER_TEST
#define HEADER_TEST

const char* TEST_CONST = "Testing" ;

class some
{
// members
} ;

#endif


When I checked the symbol table, it was reported that,
[Index] Value Size Type Bind Other Shndx Name
[4] | 0| 4|OBJT |GLOB |0 |3 |TEST_CONST


Why?
 
I

Ivan Vecerina

| const has internal linkage in C++, but external linkage in C.
| Am I right ?
Yes.

| But, linker reports multiply-defined error if the
| following header is included in multiple .cpp files.
....
| const char* TEST_CONST = "Testing" ;

Note that this is not a constant variable.
It is a non-const pointer to statically allocated constant
characters;

You should try:
const char* const TEST_CONST = "Testing" ;
Or:
const char TEST_CONST[] = "Testing" ;

hth,
Ivan
 
S

sks_cpp

Ivan Vecerina said:
| const has internal linkage in C++, but external linkage in C.
| Am I right ?
Yes.

What exactly does that mean? (internal linkage vs external linkage)
 
A

Attila Feher

sks_cpp wrote:
[SNIP]
What exactly does that mean? (internal linkage vs external linkage)

Lame description:

External linkage: has a name which others can use (an exported name in the
object file generated from the source code).

Internal linkage: the compiler will not give an externally visible name for
the thing, so others (other .c or .cpp files) will not be able to see it by
name.

By name is important, since I can still give its address. The most famous
thing with internal linkage is statci global variables. Their name is only
visible in the source file where they are defined.
 
R

ramesh

Ivan Vecerina said:
| const has internal linkage in C++, but external linkage in C.
| Am I right ?
Yes.

| But, linker reports multiply-defined error if the
| following header is included in multiple .cpp files.
...
| const char* TEST_CONST = "Testing" ;

Note that this is not a constant variable.
It is a non-const pointer to statically allocated constant
characters;

You should try:
const char* const TEST_CONST = "Testing" ;
Or:
const char TEST_CONST[] = "Testing" ;

hth,
Ivan

Hi,
Can you please clarify me on external and internal linkage.
regards,
Ramesh
 
L

llewelly

[comp.unix.solaris removed.]

const has internal linkage in C++, but external linkage in C.
Am I right ?

No. A long time ago, in the days of ARM C++, const had internal
linkage, but that was changed in the early years of
standardization. I can't recall the last time I used a compiler
that didn't implement the 'new' const has external linkage rule.
 
A

Andrey Tarasevich

llewelly said:
...

No. A long time ago, in the days of ARM C++, const had internal
linkage, but that was changed in the early years of
standardization. I can't recall the last time I used a compiler
that didn't implement the 'new' const has external linkage rule.

No. By default 'const' objects have internal linkage in C++. The problem
with OP's code is that the object is not 'const'.
 
L

llewelly

Andrey Tarasevich said:
No. By default 'const' objects have internal linkage in C++.

You are correct - I was thinking of inline functions, for some reason,
which once had internal linkage but now have external linkage.
 
I

Ivan Vecerina

| > | > | const has internal linkage in C++, but external linkage in C.
| > | Am I right ?
| > Yes.
.....
| > hth,
| > Ivan
|
| Hi,
| Can you please clarify me on external and internal linkage.

Well, Attila probably gave an explanation, but here's my throw at it.
External linkage = accessible from other compilation units (.cpp files).

Given the definition of a global variable with external linkage,
such as:
namespace n { int g; }
any other translation unit may access it by declaring the variable
again:
namespace n { extern int g; }
NB: for global variable declaration, 'extern' must be used to
explicitly specify that this is a declaration, but not
a definition(/"allocation") of the variable.

It also means that if another source file/library was to define a
global variable of the same name, an error will occur (typically
reported as a name collision at link time):
namespace n { int g; } // in a second file --> link error.


Static variables, as well as constants in namespace(=global) scope,
have internal linkage. It means that two translation units can
use a global variable that has the same name: the two variables
are allocated independently, or duplicated, and will not collide.


Internal/external linkage exists also for functions (e.g. static
non-member functions have internal linkage) and for classes (a
class defined in function scope is also currently said to have
internal linkage: it will not be accessible from the outside,
or collide with an identically named class in another function).
[ for classes IIRC, this might change in the next C++ standard,
to address the issue described in the next paragraph ].


Other than these usage aspects, the only real limitation of objects
that have internal linkage is that they cannot be used as template
parameters (~because of how link names are generated for templates).
This means that a predicate class used as a template parameter
cannot currently be defined within a function.


This limitation of objects with internal linkage is the main reason
why 'static' for global objects is considered to be deprecated.
The modern alternative is to use anonymous namespaces:
namespace { int g; } // external linkage, but never collides
During the compilation of each file, a unique 'prefix' is generated
for objects defined in an anonymous namespace.
They have external linkage, but will never "collide" because
of the unique prefix.



I hope you'll find these explanations useful,
Ivan
 
I

Ivan Vecerina

| Internal/external linkage exists also for functions (e.g. static
| non-member functions have internal linkage) and for classes (a
| class defined in function scope is also currently said to have
| internal linkage: it will not be accessible from the outside,
| or collide with an identically named class in another function).
Errata: actually, it is said to have no linkage.
To quote the standard, there are actually 3 types of linkage --
3.5/2:
A name is said to have linkage when it might denote the same object,
reference, function, type, template, namespace or value as a name introduced
by a declaration in another scope:

— When a name has external linkage, the entity it denotes can be referred to
by names from scopes of other translation units or from other scopes of the
same translation unit.

— When a name has internal linkage, the entity it denotes can be referred to
by names from other scopes in the same translation unit.

— When a name has no linkage, the entity it denotes cannot be referred to by
names from other scopes.



Ivan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top