473,378 Members | 1,527 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Where to define a const string?

I am looking for a graceful way to declare a string const that is to be
visible across many files.

If I do this:

//----hdr.h

const char * sFoo = "foo";

//file.cpp
#include <hdr.h>

strcpy(string, sFoo);
//anotherfile.cpp
#include <hdr.h>

strcpy(string, sFoo);
The linker complains that sFoo is multiply defined.

I don't want to use a #define as it breaks type safety. I don't want to have
multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?

RDeW
Aug 26 '05 #1
12 16095
Riley DeWiley wrote:
I am looking for a graceful way to declare a string const that is to be
visible across many files.

If I do this:
[snip example]
The linker complains that sFoo is multiply defined.

I don't want to use a #define as it breaks type safety. I don't want to
have multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?

RDeW


Header file:
extern const char sFoo[];

In (one) source file (exactly which doesn't matter):
const char sFoo[] = "foo";

--
λz.λi.i(i((λn.λm.λz.λi.nz(λq.mqi))((λn.λz .λi.n(nzi)i)(λz.λi.i(((λn.λz.λi.n
(nzi)i)(λz.λi.i(iz)))zi)))((λn.λz.λi.n(nzi)i) (λz.λi.i(iz)))zi))
Aug 26 '05 #2
Riley DeWiley wrote:
I am looking for a graceful way to declare a string const that is to be
visible across many files.

If I do this:

//----hdr.h

const char * sFoo = "foo";

//file.cpp
#include <hdr.h>

strcpy(string, sFoo);
//anotherfile.cpp
#include <hdr.h>

strcpy(string, sFoo);
The linker complains that sFoo is multiply defined.

I don't want to use a #define as it breaks type safety. I don't want to have
multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?


If you declare it in the header

const char * const sFoo = "foo";

which creates multiple copies. To avoid that you could do

extern const char sFoo[];

in the header and in _one_of_the_C++_source_files_ do

extern const char sFoo[] = "foo";

The linker will be happy and you will have the only definition of the
string in the program.

V
Aug 26 '05 #3
Riley DeWiley wrote:

I don't want to use a #define as it breaks type safety.
No, it doesn't.

#define sFoo "foo"

Every place you use the identifier sFoo you'll get a string literal. Its
type, however, is array of const char rather than pointer to const char,
which is what your code uses.
I don't want to have
multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?


In the header:
const char *sFoo;

In one implementation file:
const char *sFoo = "foo";

The suggestion the other messages make, to use const char sFoo[], also
works, but just like the macro, it makes sFoo a different type from what
you asked for.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Aug 26 '05 #4
Pete Becker wrote:
Riley DeWiley wrote:

I don't want to use a #define as it breaks type safety.
No, it doesn't.

#define sFoo "foo"

Every place you use the identifier sFoo you'll get a string literal. Its
type, however, is array of const char rather than pointer to const char,
which is what your code uses.
I don't want to have
multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?


In the header:
const char *sFoo;

In one implementation file:
const char *sFoo = "foo";


This is wrong. The first will create a pointer, initialized to NULL, in each
file it's included in. The second will create yet another pointer,
initialized to pointing to the constant string needed.

The suggestion the other messages make, to use const char sFoo[], also
works, but just like the macro, it makes sFoo a different type from what
you asked for.


The array will automatically cast into const char * when needed, so it
doesn't matter.

--
λz.λi.i(i((λn.λm.λz.λi.nz(λq.mqi))((λn.λz .λi.n(nzi)i)(λz.λi.i(((λn.λz.λi.n
(nzi)i)(λz.λi.i(iz)))zi)))((λn.λz.λi.n(nzi)i) (λz.λi.i(iz)))zi))
Aug 27 '05 #5

Victor Bazarov wrote:
Riley DeWiley wrote:
I am looking for a graceful way to declare a string const that is to be
visible across many files.

If I do this:

//----hdr.h

const char * sFoo = "foo";

//file.cpp
#include <hdr.h>

strcpy(string, sFoo);
//anotherfile.cpp
#include <hdr.h>

strcpy(string, sFoo);
The linker complains that sFoo is multiply defined.

I don't want to use a #define as it breaks type safety. I don't want to have
multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?


If you declare it in the header

const char * const sFoo = "foo";

which creates multiple copies. To avoid that you could do

extern const char sFoo[];

in the header and in _one_of_the_C++_source_files_ do

extern const char sFoo[] = "foo";

The linker will be happy and you will have the only definition of the
string in the program.

V


Const declarations by default have internal linkage, so the declaration
can remain in the header file once it's changed from a pointer to an
array. No source files need to be changed.

In other words change this declaration in the header file:

const char * const sFoo = "foo";

to this:

const char const sFoo[] = "foo";

And the multiple definition error will be fixed - no matter how many
source files actually include sFoo's declaration.

Greg

Aug 27 '05 #6
Bryan Donlan wrote:
Pete Becker wrote:

I don't want to have
multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?

In the header:
const char *sFoo;

In one implementation file:
const char *sFoo = "foo";

This is wrong. The first will create a pointer, initialized to NULL, in each
file it's included in.


You're right: it needs an extern in front.

The suggestion the other messages make, to use const char sFoo[], also
works, but just like the macro, it makes sFoo a different type from what
you asked for.

The array will automatically cast into const char * when needed, so it
doesn't matter.


First, a cast is something you write in your code to tell the compiler
that you want a conversion. Second, there are two contexts in which the
conversion from array into pointer to its first element is not done. The
two types are not the same.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Aug 27 '05 #7
Pete Becker wrote:

Second, there are two contexts in which the
conversion from array into pointer to its first element is not done. The
two types are not the same.


Actually, that's true in C. In C++ there are more. And, in both
languages, this is not a conversion, but a decay: the name of an array
decays into a pointer to its first element in most contexts. And, of
course, it is still true that the two types are not the same. Try this:

a.c
---
char text[] = "abcd";

void f()
{
puts(text);
}

b.c
---
extern char *text;
void f();

int main()
{
*text = 'e';
f();
return 0;
}

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Aug 27 '05 #8
Riley DeWiley <ri***********@gmail.com> wrote:
I am looking for a graceful way to declare a string const that is to be
visible across many files.

If I do this:

//----hdr.h

const char * sFoo = "foo";

//file.cpp
#include <hdr.h>

strcpy(string, sFoo);
//anotherfile.cpp
#include <hdr.h>

strcpy(string, sFoo);
The linker complains that sFoo is multiply defined.

I don't want to use a #define as it breaks type safety. I don't want to have
multiple copies of '
const char * sFoo = "foo";' littering my code.

What is the most compact and maintainable way to do this?


Would an #include guard work?
//-----hdr.h
#ifndef HDR_H
#define HDR_H

const char* sFoo = "foo";

#endif

--
Marcus Kwok
Sep 20 '05 #9
Riley DeWiley <ri***********@gmail.com> wrote:
I am looking for a graceful way to declare a string const that is to be
visible across many files.
[...]
What is the most compact and maintainable way to do this?


Probably not the most compact way, but I suppose it would fit into the
maintainable and correct categories.
//--- MagicString.h

#ifndef MAGIC_STRING_H__
#define MAGIC_STRING_H__

extern const char* const gMagicString;

#endif
//--- MagicString.cpp

#include "MagicString.h"

const char* const gMagicString = "I am a magic string!";
//--- test.cpp

#include "MagicString.h"
#include <iostream>

int main()
{
std::cout << gMagicString << '\n';
}
Regards,

--
Ney André de Mello Zunino
Sep 20 '05 #10
Just a reminder on your include guards: words with double underscores
are reserved for the implemention.

Sep 20 '05 #11
Marcelo Pinto <mp******@gmail.com> schrieb:
Just a reminder on your include guards: words with double underscores
.... at the beginning ...
are reserved for the implemention.


Regards, Markus
Sep 25 '05 #12
Markus Becker wrote:
Marcelo Pinto <mp******@gmail.com> schrieb:
Just a reminder on your include guards: words with double underscores


... at the beginning ...


Nope: double underscores are off limits regardless of their position within
identifiers. See [17.4.3.1.2/1]:

17.4.3.1.2 Global names [lib.global.names]

1 Certain sets of names and function signatures are always reserved
to the implementation:

? Each name that contains a double underscore (__) or begins with
an underscore followed by an uppercase letter (2.11) is reserved
to the implementation for any use.

are reserved for the implemention.

Best

Kai-Uwe Bux

Sep 25 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: selder21 | last post by:
Hello, I have a class with constructor taking a const string&. Now i want to call this constructor with a string literal. Because this is of type char* there are overload resolution conflicts....
4
by: sam | last post by:
Hi, Is there any way I can prevent people use some binary disambler (eg. strings in unix) to view the const string value in a compiled C++ program? Sam.
3
by: QQ | last post by:
How to define a string? Usually we can #define MAX 30 However if I'd like to define a string const can I? #define S "Hello"
1
by: Erik Tamminga | last post by:
Hi, I'm totally bluffed: how can a 'public const string name = "myname";' ever evaluate to null? I have the following class: public class MIB2 { public const string org = "1.3";
6
by: ESPN Lover | last post by:
I'm fairly new to the whole .NET and OOP programming so bear with me. In the past if I wanted to have constants defined that I could use in my code, I'd include them either the file or as an...
2
by: msaladin | last post by:
Hi all, I spent today with finding an error, I found it, though I don't no why. I have a class with static constants, like this: class EXPORT_API BusConstants { public: static const...
5
by: Jae | last post by:
Real(const string &fileName) { FILE * myInputFile = fopen(fileName, "rt"); ..... fclose(myInputFile);
2
by: martin-g | last post by:
Hi. Almost every application have to write out some messages to the user. The question is how to store them. For example, while programming for Windows in C++ we could store these messages as...
8
by: Ook | last post by:
I have a function getStuff, and two choices of implementation: const string *getStuff() { return &_stuff; } or const string getStuff()
2
by: wizofaus | last post by:
Given the following code: public class Test { static unsafe void StringManip(string data) { fixed (char* ps = data) ps = '$'; }
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.