By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,583 Members | 617 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,583 IT Pros & Developers. It's quick & easy.

Const declaration in header files

P: n/a
Hi

Just going over some grey areas in my knowledge in C++:

1) If I have

const int SomeConst = 1;

in a header file, it is global, and it is included in multiple translations
units, but it is unused, I know that it does not take up storage in the
final executable.

What about the following

const double SomeConst2 = 2.0;
const char SomeConst3[] = "A value1";
const char *SomeConst4 = "A value 2";

do they wind up in the final executable?

2) What about the last two statements with const missing and placed in a
header file

char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";

At this point, including in 2+ translation units would fall foul of the one
definition rule, right?

3) If I have

const int SomeConst = 1;

in a header file, it is global, is it static or extern by default?

Thanks

Stephen Howe
Jun 27 '08 #1
Share this Question
Share on Google+
10 Replies


P: n/a
"Stephen Howe" <sjhoweATdialDOTpipexDOTcomkirjutas:
Hi

Just going over some grey areas in my knowledge in C++:

1) If I have

const int SomeConst = 1;

in a header file, it is global, and it is included in multiple
translations units, but it is unused, I know that it does not take up
storage in the final executable.
If something is unused, the compiler can throw it out on "as-if" basis,
or then not. This is mostly QOI issue. If the variable definitions are
incorrect and the standard requires a diagnostic about that, the
implementation has to produce the diagnostic regardless of whether he
would encode the variables in the executable or not.

If the code happens to take the address of i somewhere, the compiler is
obliged to ensure that at runtime there will be an int variable present
with the proper value, so that the address can be taken. This most
probably means that the value is somehow encoded in the executable - I
guess this is what you mean when you talk about storage in the
executable.

However, this is all not so important, unless you work on embedded
systems, counting single bytes. What is important that in C++ the const
object definitions can legally appear in multiple translation units,
without causing linker errors about multiple definitions. Of course, all
definitions must be identical. This enables to use such definitions in
common header files instead of ancient C macros.
>
What about the following

const double SomeConst2 = 2.0;
const char SomeConst3[] = "A value1";
The same as 'const int'. These definitions can be included in many
translation units.
const char *SomeConst4 = "A value 2";
Here SomeConst4 is not const, so the rule does not apply and one will
most probably get linker errors when trying to include this in multiple
translation units. Add 'const' to make it working.
>
do they wind up in the final executable?
Why do you care?
>
2) What about the last two statements with const missing and placed
in a header file

char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";
The const you dropped is not the top-level one, so it does not have any
significance here.
>
At this point, including in 2+ translation units would fall foul of
the one definition rule, right?
The same as for SomeConst3 (ok) and SomeConst4 (fails).
>
3) If I have

const int SomeConst = 1;

in a header file, it is global, is it static or extern by default?
This is not the right termonology, the standard speaks about external and
internal linkage, etc. I am not sure I can get the details right so I
skip that.

hth
Paavo
Jun 27 '08 #2

P: n/a
On Sat, 24 May 2008 19:22:55 +0100, "Stephen Howe"
<sjhoweATdialDOTpipexDOTcomwrote in comp.lang.c++:
Hi

Just going over some grey areas in my knowledge in C++:

1) If I have

const int SomeConst = 1;

in a header file, it is global, and it is included in multiple translations
units, but it is unused, I know that it does not take up storage in the
final executable.
It is not "global", C++ does not have anything that maps all that well
to what is normally meant by that concept. The const keyword used at
namespace scope in C++ provides internal linkage, unless you
specifically add the extern keyword as well.

What you have defined is a constant int with internal linkage. It
might or might not take up storage in the final executable, if you do
not take its address. If you do take its address and use it in a way
such that compiler cannot verify that it won't be dereferenced, then
it must take up space at run time when that address is used.

If you include the header file in multiple translation units, each
translation unit will wind up with its own distinct copy.
What about the following

const double SomeConst2 = 2.0;
const char SomeConst3[] = "A value1";
const char *SomeConst4 = "A value 2";

do they wind up in the final executable?
That is entirely up to your compiler, not the language, unless again
you use the address of these objects in some way.
2) What about the last two statements with const missing and placed in a
header file

char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";

At this point, including in 2+ translation units would fall foul of the one
definition rule, right?
Well, you would almost certainly have complaints from the linker.
3) If I have

const int SomeConst = 1;

in a header file, it is global, is it static or extern by default?
No, it isn't global, C++ doesn't really have "global". The closest
C++ has to global is external linkage. But defining something with
external linkage in one translation unit does not automagically make
it "global", that is accessible by name throughout the entire program.

Any objects defined at namespace scope have static storage duration.
If the definition includes either or both of the const or static
keywords, the object has static storage duration and internal linkage.
If the definition does not include either of these keywords, the
object has static storage duration and external linkage.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jun 27 '08 #3

P: n/a
On Sat, 24 May 2008 15:46:58 -0500, Paavo Helde <no****@ebi.eewrote
in comp.lang.c++:
"Stephen Howe" <sjhoweATdialDOTpipexDOTcomkirjutas:
Hi

Just going over some grey areas in my knowledge in C++:

1) If I have

const int SomeConst = 1;

in a header file, it is global, and it is included in multiple
translations units, but it is unused, I know that it does not take up
storage in the final executable.
[snip]
However, this is all not so important, unless you work on embedded
systems, counting single bytes. What is important that in C++ the const
object definitions can legally appear in multiple translation units,
without causing linker errors about multiple definitions. Of course, all
definitions must be identical. This enables to use such definitions in
common header files instead of ancient C macros.
Actually, the definitions need not be identical at all, especially for
built-in types.

I can have in one source file:

const int SomeConst = 1;

....and in another:

const int SomeConst = 42;

....with no problem at all.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jun 27 '08 #4

P: n/a
On May 24, 8:22 pm, "Stephen Howe" <sjhoweATdialDOTpipexDOTcomwrote:
Just going over some grey areas in my knowledge in C++:
1) If I have
const int SomeConst = 1;
in a header file, it is global, and it is included in multiple
translations units, but it is unused, I know that it does not
take up storage in the final executable.
Wrong on both counts. First, the variable has internal linkage,
which means that there is a different SomeConst for each
translation unit in which it is defined. And second, whethere
it does or does not take up storage is purely implementation
defined. Conceptually, it takes up sizeof(int) bytes in each
translation unit; most compilers probably will detect that if it
is not used, this fact makes no difference, and will suppress
it, but this is really an optimization.
What about the following
const double SomeConst2 = 2.0;
const char SomeConst3[] = "A value1";
const char *SomeConst4 = "A value 2";
do they wind up in the final executable?
Same rules as above for the first two. As far as the standard
is concerned, they are physically present in each translation
unit; if they aren't, it's the result of a space optimization by
the compiler.

The third is different: because the variable itself isn't const,
the declaration has external linkage by default, and its
presence in more than one translation unit is a violation of the
one definition rule.
2) What about the last two statements with const missing and
placed in a header file
char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";
These do have external linkage, so the names SomeConst5 and
SomeConst6 refer to the same object when used in different
translation units. And as you say...
At this point, including in 2+ translation units would fall
foul of the one definition rule, right?
Right. The const equivalent to the above would be:

extern char const SomeConst5[] = "A value 3";
extern char * const SomeConst6 = "A value 4";

Similarly, to make SomeConst5 and SomeConst6 have internal
linkage, without being const:

static char SomeConst5[] = "A value 3";
static char *SomeConst6 = "A value 4";

For *definitions* at namespace scope, you can always specify the
linkage explicitly, by means of extern or static, provided you
furnish an explicit initializer. For *declarations* at
namespace scope, you can always force external linkage by
specifying extern; there are cases, I think, where you cannot
create a declaration with internal linkage which is not also a
definition (if the variable is const, for example). The default
depends on whether the variable itself is const or not.
3) If I have
const int SomeConst = 1;
in a header file, it is global, is it static or extern by default?
static.

The rules are far from orthogonal, and the relationships between
the keywords and what they do are complex and arbitrary. For
historical reasons, of course---no one would design this sort of
thing intentionally from scratch.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #5

P: n/a
On May 24, 10:46 pm, Paavo Helde <nob...@ebi.eewrote:
"Stephen Howe" <sjhoweATdialDOTpipexDOTcomkirjutas:
Just going over some grey areas in my knowledge in C++:
1) If I have
const int SomeConst = 1;
in a header file, it is global, and it is included in
multiple translations units, but it is unused, I know that
it does not take up storage in the final executable.
If something is unused, the compiler can throw it out on
"as-if" basis, or then not. This is mostly QOI issue. If the
variable definitions are incorrect and the standard requires a
diagnostic about that, the implementation has to produce the
diagnostic regardless of whether he would encode the variables
in the executable or not.
If the code happens to take the address of i somewhere, the
compiler is obliged to ensure that at runtime there will be an
int variable present with the proper value, so that the
address can be taken. This most probably means that the value
is somehow encoded in the executable - I guess this is what
you mean when you talk about storage in the executable.
The as-if rule holds here as well. Probably the most frequence
case of "taking the address" of an int const is when passing it
to an int const& argument; such arguments generally only result
from the expansion of a template, and in the absense of export,
the compiler has access to the source code of the function, and
can (potentially, at least) see if in fact, it could use the
value directly just as well. Thus, if you have an
std::vector<int>, and do a push_back( SomeConst ) on it, there's
a very good chance that the compiler will not need to allocate
memory for SomeConst then either, despite the fact that in the
abstract machine, it has "taken the address" of the constant.
However, this is all not so important, unless you work on
embedded systems, counting single bytes. What is important
that in C++ the const object definitions can legally appear in
multiple translation units, without causing linker errors
about multiple definitions. Of course, all definitions must be
identical. This enables to use such definitions in common
header files instead of ancient C macros.
It can be important for two reasons. The first, of course, is
if you have header files with lots of such values, say a couple
hundred, and you end up incorporating the header in many very
small source files. In such cases, while not likely, it *can*
end up making a difference. Particularly if those source files
also have some static variables, which becaue of the extra
variables end up on separate pages in virtual memory. Program
size is important today, for reasons of locality. (The number
of programs affected will be very small, of course.)

The second is that using the variable in a template may cause
problems. The template definition will also be included in
multiple translation units, and according to the standard, there
will be undefined behavior if the token sequence of the
definition differs, OR if any name binding differs. In this
case, the name binding of SomeConst will be different in each
translation unit, i.e. the symbol SomeConst will refer to a
different entity in each translation unit. The standard does
make an exception to this if the symbol is an integral constant
expression (as it is here), with the same type and initializer
value everywhere, *and* only if the address of the object is not
used. (Note that passing the value by reference is using the
address!)

[...]
do they wind up in the final executable?
Why do you care?
Locality? Limited memory? (I've worked on systems where the
entire application had to fit into 64KB, including the OS.)
2) What about the last two statements with const missing and placed
in a header file
char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";
The const you dropped is not the top-level one, so it does not
have any significance here.
In the second line. In the first, it changes the linkage.
At this point, including in 2+ translation units would fall foul of
the one definition rule, right?
The same as for SomeConst3 (ok) and SomeConst4 (fails).
Do you mean that SomeConst3 and SomeConst5 are the same? I
don't think so.

Actually, the more I think about it, the less sure I am. In C,
at least, there is no such thing as a const array, so the const
isn't top level. G++ treats them as if the arrays themselves
were const, however (i.e. as if the const were top level).
3) If I have
const int SomeConst = 1;
in a header file, it is global, is it static or extern by default?
This is not the right termonology, the standard speaks about
external and internal linkage, etc. I am not sure I can get
the details right so I skip that.
In this case, supposing that the definition is at namespace
scope, it is internal linkage. But the rules aren't really very
orthogonal, and can easily lead to confusion.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #6

P: n/a
James Kanze <ja*********@gmail.comkirjutas:
On May 24, 10:46 pm, Paavo Helde <nob...@ebi.eewrote:
>"Stephen Howe" <sjhoweATdialDOTpipexDOTcomkirjutas:
2) What about the last two statements with const missing and placed
in a header file
char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";
>The const you dropped is not the top-level one, so it does not
have any significance here.

In the second line. In the first, it changes the linkage.
Yes, you are right. I was not prepared to have yet more subtleties,
especially such seemingly illogical ones. It's my fault I know, but I
cannot understand why should const char array have different linkage than
variable char array? Probably something to do with C legacy?

OK, I can see some logic here, if the arrays are considered to be
extension of a single object to case N>1, then it makes sense that
extension of const/non-const object shares the same linkage as the single
object. However, in almost all other contexts the array is equivalent to
a pointer to a object - I think this is the source of my confusion.

Regards
Paavo
Jun 27 '08 #7

P: n/a
On May 25, 10:39 pm, Paavo Helde <nob...@ebi.eewrote:
James Kanze <james.ka...@gmail.comkirjutas:
On May 24, 10:46 pm, Paavo Helde <nob...@ebi.eewrote:
"Stephen Howe" <sjhoweATdialDOTpipexDOTcomkirjutas:
2) What about the last two statements with const missing and placed
in a header file
char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";
The const you dropped is not the top-level one, so it does
not have any significance here.
In the second line. In the first, it changes the linkage.
Yes, you are right. I was not prepared to have yet more
subtleties, especially such seemingly illogical ones. It's my
fault I know, but I cannot understand why should const char
array have different linkage than variable char array?
Probably something to do with C legacy?
Well, nothing involving const is due to C legacy, since C++ had
const before C did. I'm pretty sure that the initial
modiviation for const affecting linkage is due to things like:

int const dim = 43 ;

In C++, `dim' has been a constant integral expression from the
day const was introduced (where as it is not a constant integral
expression in C, even today). To work as a constant integral
expression, of course, you need the initializer. And there are
a lot of constant integral expressions which you'll want in
header files as well. If the linkage of the above were external
(as it is in C, or without the const), you'd have to write:

static int const dim = 43 ;

if you wanted to avoid duplicate definitions. And while
personally, that doesn't bother me, apparently, it did bother
some early users, and the rule was made (very early) that const
variables default to internal linkage (i.e. as if they were
declared static).

All of this was long before templates, of course, so the fact
that you cannot use the address of dim as a template argument
wasn't considered, nor the fact that passing dim by reference in
a function template results in undefined behavior.
OK, I can see some logic here, if the arrays are considered to
be extension of a single object to case N>1, then it makes
sense that extension of const/non-const object shares the same
linkage as the single object. However, in almost all other
contexts the array is equivalent to a pointer to a object - I
think this is the source of my confusion.
An array is never really equivalent to a ponter to an object.
It converts to a pointer to the first element in some specific
cases, in expressions, but there is still a conversion involved.
A pointer designates an object; it is NOT that object, nor does
it contain that object. An array contains its members, and is
actually more like a struct than a pointer.

The fact remains that in:
int const array[ N ] ;
it is the "int" that is const, and not the array, so the const
isn't top level, and that at least in C, "If the specification
of an array type includes any type qualifiers, the element type
is so qualified, not the array type." So even if you write:
typedef int A[ N ] ;
A const array ;
at least in C, it is not a top level const (not that this makes
a difference in C). So strictly speaking, I don't think that
the array definition has top level const, according to the
standard. On the other hand, at least three compilers (Sun CC,
g++ and VC++) treat it as if it does.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #8

P: n/a
On May 26, 6:28 am, "Alf P. Steinbach" <al...@start.nowrote:
* Paavo Helde:
On May 24, 10:46 pm, Paavo Helde <nob...@ebi.eewrote:
"Stephen Howe" <sjhoweATdialDOTpipexDOTcomkirjutas:
2) What about the last two statements with const missing and placed
in a header file
char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";
The const you dropped is not the top-level one, so it does not
have any significance here.
In the second line. In the first, it changes the linkage.
Yes, you are right. I was not prepared to have yet more
subtleties, especially such seemingly illogical ones. It's
my fault I know, but I cannot understand why should const
char array have different linkage than variable char array?
Probably something to do with C legacy?
The two declarations shown above do not have top-level const.
They provide assignable variables. Since they're assignable
variables, not 'const', they have external linkage by default.
The real question here is:
char const SomeConst[] = "A value" ;
Does SomeConst have external linkage, or internal? Intuitively,
I would say internal (and g++, Sun CC and VC++ agree with me),
but I can't find anything in the standard to back this up. And
if this has internal linkage, how is it different from:
struct Toto
{
int const i ;
} ;
Toto x = { 43 } ;
In both cases, we have an agglomerate in which all elements are
const (but the agglomerate itself is not declared const).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #9

P: n/a
On May 26, 1:13 pm, "Alf P. Steinbach" <al...@start.nowrote:
* James Kanze:
On May 26, 6:28 am, "Alf P. Steinbach" <al...@start.nowrote:
* Paavo Helde:
On May 24, 10:46 pm, Paavo Helde <nob...@ebi.eewrote:
"Stephen Howe" <sjhoweATdialDOTpipexDOTcomkirjutas:
2) What about the last two statements with const missing and placed
in a header file
char SomeConst5[] = "A value 3";
char *SomeConst6 = "A value 4";
The const you dropped is not the top-level one, so it does not
have any significance here.
In the second line. In the first, it changes the linkage.
>Yes, you are right. I was not prepared to have yet more
subtleties, especially such seemingly illogical ones. It's
my fault I know, but I cannot understand why should const
char array have different linkage than variable char array?
Probably something to do with C legacy?
The two declarations shown above do not have top-level const.
They provide assignable variables. Since they're assignable
variables, not 'const', they have external linkage by default.
The real question here is:
char const SomeConst[] = "A value" ;
Does SomeConst have external linkage, or internal?
Internal.
It's const.
Well, that's what I think it should be, too. But I can't find
anything in the standard to back it up.
Intuitively,
I would say internal (and g++, Sun CC and VC++ agree with me),
but I can't find anything in the standard to back this up.
§3.5/3 would apply if the object, the array, itself was
declared const.
But here it's seemingly the elements that are const, and
seemingly that the array effective constness stems from arrays
not being assignable on their own.
Exactly. In C, the standard says explicitly that there's no
such thing as a const array. The C++ standard doesn't say that
in so many words, but it does say that "Any type of the form
``cv-qualifier-seq array of N T'' is adjusted to ``array of N
cv-qualifier-seq T,[ ...]'', which means that even if you write:

typedef int A[10];
A const a ;

The type of a is array of 10 const int, and the const-ness is
not top level.
There is however a non-normative note at the end of §8.3.4/1
that attempts to explain this. Presumably what it's meant to
explain is that the /intent/ of that paragraph is that
cv-qualification of array elements transfer to the array
object itself.
A very feeble attempt, IMHO. But perhaps sufficient if it were
normative.
Anyway, it explicitly says "internal linkage".
Where?
And
if this has internal linkage, how is it different from:
struct Toto
{
int const i ;
} ;
Toto x = { 43 } ;
In both cases, we have an agglomerate in which all elements are
const (but the agglomerate itself is not declared const).
cv-qualification of elements of a struct does not transfer to
the struct itself.
I know, but according to the standard, the same is true of
arrays. Only more so, because you can't declare an object of
array type const.

Anyhow, I think it's all vague enough for me to raise an issue
with the committee. I'm not sure, but judging from the behavior
of the compilers I've tested, I think that there is more or less
a consensus that the const-ness of the array elements *should*
cause internal linkage (as if the array itself were const); it's
just a question of making this clear in the wording of the
standard.

With regards to the struct above: I rather like the idea that a
PODS in which all elements are const would cause objects of that
type to be const as well, but that would definitely be an
extention, or a change in the language (and it's probably not
important enough to bother with).

Only distantly relevant to the current discussion: I don't see
anything forbidding a union to contain a const object either,
e.g.:

union U { int const a; double b ; } ;

I don't quite see how it could work, however. (Unions are being
reworked in the current draft, to remove a lot of the
restrictions. I'm not sure how this affects const elements in
unions, however.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #10

P: n/a
On May 27, 11:26 am, "Alf P. Steinbach" <al...@start.nowrote:
* James Kanze:
On May 26, 1:13 pm, "Alf P. Steinbach" <al...@start.nowrote:
There is however a non-normative note at the end of §8.3.4/1
that attempts to explain this. Presumably what it's meant to
explain is that the /intent/ of that paragraph is that
cv-qualification of array elements transfer to the array
object itself.
A very feeble attempt, IMHO. But perhaps sufficient if it were
normative.
Anyway, it explicitly says "internal linkage".
Where?
<q>
Note: an "array of N cv-qualifier-seq T" has cv-qualified type;
</q>
which I (now I see, explained below, probably incorrectly,
although opinions differ) read as an attempted explanation
that the element CV-qualification is transferred to the array
object itself, and continues, emhpasis added
<q>
such an array has *internal linkage* unless explicitly declared 'extern'
(7.1.5.1) and must be initialized as specified in 8.5.
</q>
That'll teach me to only look at the latest draft for such
things. The second part you quote above has been dropped in the
latest draft. Which is curious, because of course, the only
real intention of this that I can see is to ensure internal
linkage.
Of course if it were taken literally it would raise the issue
of auto variables with internal linkage.
Maybe that's why it was dropped. Or more accurately, replaced
by "see 3.9.3". Which says in its paragraph 2: "Any
cv-qualifiers applied to an array type affect the array element
type, not the array type (8.3.4)." And we're back to where we
started.
In the C++0x draft, at least my old version, the latter quoted
part is removed, and instead there is a reference to §3.9.3
about CV-qualification, where it's made clear that my
interpretation above is not the one to be adopted in C++0x,
Except that "an `array of N cv-qualifier-seq T' has cv-qualified
type" seems to directly contradict "Any cv-qualifiers applied to
an array type affect the array element type, not the array
type". (The contradiction is in the "not the array type".)

So someone has been doing something, but it still looks like a
case of the left hand not knowing what the right hand is doing
to me. And quite frankly, I'd prefer that arrays of const T
behave as const array of const T. (Actually, I'd prefer that
const didn't affect the linkage, and that arrays behaved like
other composite types, i.e. with copy, no implicit conversion to
pointer, etc., etc. But it's far too late for either of those
changes.)
Current and C++0x
§3.9.3/2
"Any cv-qualifiers applied to an array type affect the array
element type, not the array type (8.3.4)."
The change in §8.3.4/1 wording, removal of that part about
internal linkage, follows core language Defect Report #112
discussion,
http://www.open-std.org/jtc1/sc22/wg...fects.html#112
which touches on the linkage issue but does not resolve it or
really discuss it (the only concern is that "volatile" should
not result in internal linkage).
Hm.
I see we're finding most of the same passages (although I'd
missed the DR).
[snip]
Anyhow, I think it's all vague enough for me to raise an issue
with the committee. I'm not sure, but judging from the behavior
of the compilers I've tested, I think that there is more or less
a consensus that the const-ness of the array elements *should*
cause internal linkage (as if the array itself were const); it's
just a question of making this clear in the wording of the
standard.
I agree, good idea.
I've done so, but I really miss csc++ for this. The committee
reflectors seem more adapted to something more concrete, after a
bit of preliminary discussion.

Anyway, while I'm not totally happy with the idea that arrays
behave differently from other composite types (all elements
const does not imply composite const), arrays behave differently
from other composite types in so many other ways, and in the
absence of anyway to declare an array const, I rather think that
the best (most intuitive) solution is for the cv-qualification
of the array to be exactly that of the cv-qualification of its
elements. (It isn't in C, but in practice, in C, it doesn't
matter, since the const-ness of the array would have no
practical effects.)

Anyway, we'll see what comes of it, but in the meantime, I
wouldn't count on it being any particular way in a given
compiler. If I think it might matter, I'll explicitly add a
static or an extern (depending on what I want).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #11

This discussion thread is closed

Replies have been disabled for this discussion.