How am I supposed to define this namespace variable?

A

A

Header file:

namespace MyNameSpace
{
extern const wchar_t CharArr[];
extern const int IntArr[];
}

Src file:

const wchar_t MyNameSpace::CharArr[] = "abc";
const int MyNameSpace::IntArr[5] = { 1,2,3,4,5};


-- the problem - when I access these variables I get a runtime error as if I
was trying to access undefined part of memory. But I don't understand why...
variable should be defined and debugger sees them.
 
V

Victor Bazarov

Header file:

namespace MyNameSpace
{
extern const wchar_t CharArr[];
extern const int IntArr[];
}

Src file:

const wchar_t MyNameSpace::CharArr[] = "abc";
const int MyNameSpace::IntArr[5] = { 1,2,3,4,5};


-- the problem - when I access these variables I get a runtime error as if I
was trying to access undefined part of memory. But I don't understand why...
variable should be defined and debugger sees them.

The object declared 'const' has internal linkage by default. Make sure
to include your header in the source file where you define those variables.

V
 
A

A

Victor Bazarov said:
The object declared 'const' has internal linkage by default. Make sure to
include your header in the source file where you define those variables.

I have included header in source. Is the above code valid? It compiles and
runs. There may be an issue with runtime debugger if the code is valid.
 
A

Alf P. Steinbach

I have included header in source. Is the above code valid? It compiles and
runs. There may be an issue with runtime debugger if the code is valid.

Victor's information (first sentence quoted) is wrong: the "extern" is
an explicit specification of linkage, which trumps the implicit linkage.

Victor's advice (second sentence quoted) is valueless: the namespace
qualification of the definitions guarantees that you have the
declarations available at that point, so there's no point in ensuring
that you have included the header: you have already ensured that.

What you're into is one of the very ungood aspects of C++, namely TYPE
UNSAFE LINKING of arrays (e.g. a pointer can be linked to an array!).

If you absolutely insist on a separately compiled definition you can either

* specify the array bounds in header, or

* have only pointers in the public interface, or

* use higher level types such as std::string and std::vector (but then,
due to the "static initialization fiasco" problem, better just provide
functions to obtain the values, not the values themselves).

However, I would just

/provide the values directly in the header/,

and rely on the compiler to optimize away duplicates in multiple
translation units.

For more info about the type unsafe linking of arrays, see e.g. <url:
http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c/7439261#7439261>.
I hate to refer to Stack Overflow, IMO the main Herb Schildt site on the
net, but I wrote that FAQ item myself. So.


Cheers & hth.,

- Alf

PS: Sorry for first, inadvertently, sending this as an e-mail reply.
 
A

A

Alf P. Steinbach said:
/provide the values directly in the header/,

thanks for replying. I have indeed provided values in the header itself and
that was my original plan. it compiled and worked.
debugger sees the array. I use it to store values and assign them when
needed, but when I assign it to UnicodeString (in C++ Builder) it pops
CodeGuard error. The memory doesn't seem uninitialized. I am therefore
suspecting and issue with CodeGuard, it is certainly not impossible, I've
already seen strange CodeGuard errors, but for the sake of the human error I
assumed first that it might be me doing something wrong.
For more info about the type unsafe linking of arrays, see e.g. <url:
http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c/7439261#7439261>. I
hate to refer to Stack Overflow, IMO the main Herb Schildt site on the
net, but I wrote that FAQ item myself. So.

thanks again. any help is always appreciated.
 
M

Martin Shobe

Presumably Victor intended his second sentence to be read as the logical
conclusion of the first: you need to include the header because
otherwise the const object will have internal linkage (it will not see
the extern declaration). I am sure he knows that the explicit "extern"
trumps implicit linkage.

I realise that Alf is not reading most people's postings to this
newsgroup (including mine), but leaving Alf's lack of comprehension of
Victor's point aside, surely he is wrong about namespaces, and that to
see the extern declaration you _must_ include the header, whether or not
they are in a particular namespace. Is Alf being a total plinker, or
have I missed something new in C++11 (neither clang++ nor g++ think he
is right).

I don't think Alf was saying that. What he was saying was that you will
get an error if the declarations aren't visible because the
nested-name-specifier and a lack of declarations is ill-formed. (See
3.4.3.1 in n3242.)
In addition, is Alf really right that in the absence of an explicit
statement of the array size in the extern declaration, that declaration
is treated as declaring a pointer by pointer decay applied to the
declaration itself (I can see that it might be true, but it seems odd
nonetheless)? Both clang++ and g++ accept the OP's original code
without warnings with -Wall, and clang++ is pretty good at warning
about these things. They also emit the expected code, with extern
linkable const variables.

As far as I can tell, Alf is incorrect here. The declarations declare
arrays of unknown size not pointers. See 8.3.4.1 in n3242. (He is
correct that about the dangers of C++'s type unsafe linking, but that
isn't the problem with the code we've seen so far.)

Martin Shobe
 
A

Alf P. Steinbach

On 12/2/2013 5:25 PM, Chris Vine wrote:
[snip attack]

The part of Chris' posting that you quoted contained -- presumably by
design -- only misrepresentation.

He's that kind of person.

Which it's an advantage to be very aware of.

As far as I can tell, Alf is incorrect here. The declarations declare
arrays of unknown size not pointers. See 8.3.4.1 in n3242.

You mean, not "Alf is incorrect" but

"Chris Vine, a known troll going back many years in clc++, is yet again
misrepresenting someone -- in this case Alf".

The code in question does not involve pointers, so any argument based on
that supposition should better be directed to the troll.

I suggest just killfiling him, along with some others (not all of them
are trolls, but all are worth ignoring for me in clc++):

condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,contains,dombo)"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,is,[email protected])"
condition="AND (from,contains,chris) AND (from,contains,vine)"
condition="AND (from,contains,vlad.moscow) AND (from,contains,)"

(He is
correct that about the dangers of C++'s type unsafe linking, but that
isn't the problem with the code we've seen so far.)

I've already stated that the unsafe linking of arrays in C++ is the
problem, and I have linked to more detailed writings of mine citing the
relevant standardese, and I have suggested workable concrete fixes.

Any refutation of that should better cite the reasons why the unsafe
linking isn't the problem, and why my stated solutions would not work.

Maybe that UB, in your opinion, is just /a/ problem?


Cheers & hth.,

- Alf
 
Ö

Öö Tiib

Header file:

namespace MyNameSpace
{
extern const wchar_t CharArr[];
extern const int IntArr[];
}

Src file:

const wchar_t MyNameSpace::CharArr[] = "abc";
const int MyNameSpace::IntArr[5] = { 1,2,3,4,5};

The only error I see with this code is that 'MyNameSpace::CharArr'
is initialized with narrow string literal not wide string literal.
-- the problem - when I access these variables I get a runtime error
as if I was trying to access undefined part of memory. But I don't
understand why... variable should be defined and debugger sees them.

You should post little example program that exposes the error that
you describe. Otherwise it is just guesswork about errors in code
that you have not posted. So far it looks fine.
 
A

Alf P. Steinbach

I've already stated that the unsafe linking of arrays in C++ is the
problem, and I have linked to more detailed writings of mine citing the
relevant standardese, and I have suggested workable concrete fixes.

Any refutation of that should better cite the reasons why the unsafe
linking isn't the problem, and why my stated solutions would not work.

Maybe that UB, in your opinion, is just /a/ problem?

Oh sorry...

On closer reading of the standard, that code should work, right.

If it is a compiler bug then the fixes I suggested may still fix the
problem, because most likely then the in-practice problem is related to
the unsafe linking of arrays.



Cheers,

- Alf
 
A

Alf P. Steinbach

thanks again. any help is always appreciated.

Martin Shobe pointed out elsewhere that from a formal point of view the
code should work.

Type-unsafe linking of array variables is probably the in-practice
culprit, via a compiler bug, but the code that you showed would not
compile as-is (char-based literal string as initializer for wchar_t
array), i.e. it's not the real code, so it's difficult to say for sure.

You can test your compiler with these two translation units:


[code file="foo.cpp"]
namespace MyNameSpace
{
extern const wchar_t CharArr[];
extern const int IntArr[];
}

#include <iostream>
int main()
{
using namespace std;
wcout << MyNameSpace::CharArr << endl;
}
[/code]

... and

[code file="bar.cpp"]
namespace MyNameSpace
{
extern const wchar_t CharArr[];
extern const int IntArr[];
}

const wchar_t MyNameSpace::CharArr[] = L"abc";
const int MyNameSpace::IntArr[5] = { 1,2,3,4,5};
[/code]


[example]
[D:\dev\test]
version g++ & version cl
g++ (GCC) 4.7.2
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86

[D:\dev\test]
g++ foo.cpp bar.cpp && a abc

[D:\dev\test]
cl foo.cpp bar.cpp /Feb && b
foo.cpp
bar.cpp
Generating Code...
abc

[D:\dev\test]
[/example]


A compiler bug is not guaranteed to make the above fail, but if it fails
then you know that there is a bug.

And sorry, I don't have the Borland (whatever it's now called) compiler.

The upshot, anyway, is the same as before: easy 'n good solution to
provide the values in the header, other solutions as in the earlier
bullet points.


Cheers & hth.,

- Alf
 
M

Martin Shobe

On 12/2/2013 9:11 PM, Alf P. Steinbach wrote:
[snip]
If it is a compiler bug then the fixes I suggested may still fix the
problem, because most likely then the in-practice problem is related to
the unsafe linking of arrays.

I'm not so sure about the problem being a compiler bug. I don't think
I've ever encountered a compiler bug related to the code shown. (I'm not
saying I know it's not a compiler bug, but I've used similar constructs
frequently without problems on both g++ and Microsoft's compilers.) I
think the problem is in the code not shown.

Martin Shobe
 
A

A

Martin Shobe said:
I'm not so sure about the problem being a compiler bug. I don't think I've
ever encountered a compiler bug related to the code shown. (I'm not saying
I know it's not a compiler bug, but I've used similar constructs
frequently without problems on both g++ and Microsoft's compilers.) I
think the problem is in the code not shown.

The code is much more complex than what I've shown it is just a few lines
from a few million line code. So compiler problem is possible.
Actually, not compiler but CodeGuard in C++ Builder, tool which helps detect
runtime memory violation errors. I've seen the problems with it before.
The problem disappears when I use char array instead of wchar_t and the code
is identical otherwise. So it is a problem with CodeGuard in this case.
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top