Do we prefer const char* or const char[]

1,187 views
Skip to first unread message

Andrew Scherkus

unread,
Sep 2, 2010, 3:25:52 PM9/2/10
to Chromium-dev, sat...@chromium.org

William Chan (陈智昌)

unread,
Sep 2, 2010, 3:28:30 PM9/2/10
to sche...@chromium.org, Chromium-dev, sat...@chromium.org
I think the intention of the style guide is to note that you shouldn't use global objects like std::string, not to indicate a preference for const char* const over const char[].  I personally prefer const char[], since you don't usually need that pointer.

--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Satish Sampath

unread,
Sep 2, 2010, 3:30:15 PM9/2/10
to William Chan (陈智昌), sche...@chromium.org, Chromium-dev
I've had a few reviewers in the past suggest use "const char* const" for static strings.

Albert J. Wong (王重傑)

unread,
Sep 2, 2010, 3:33:44 PM9/2/10
to sat...@chromium.org, William Chan (陈智昌), sche...@chromium.org, Chromium-dev
[ from the right address ]

That feels like it's starting to border on const happiness..


but only bordering.  I personally go with William's style of using [] where possible.

-Albert

Wan-Teh Chang

unread,
Sep 2, 2010, 3:36:30 PM9/2/10
to sche...@chromium.org, Chromium-dev, sat...@chromium.org
maruel told me
const char * name = "Chrome";
allows the compiler to perform string pooling optimization, but
const char name[] = "Chrome";
doesn't.

Wan-Teh

Satish Sampath

unread,
Sep 2, 2010, 3:38:30 PM9/2/10
to Albert J. Wong (王重傑), William Chan (陈智昌), sche...@chromium.org, Chromium-dev
That feels like it's starting to border on const happiness..


Yes, though the chromium style guide seems to recommend it.

Adam Langley

unread,
Sep 2, 2010, 3:42:04 PM9/2/10
to w...@google.com, sche...@chromium.org, Chromium-dev, sat...@chromium.org

On the flip side, "const char* name" involves an extra relocation record.

On Linux "const char name[]" is preferred because of this (see [1],
section 2.4.1).


[1] http://www.smilax.org/135/dsohowto.pdf

AGL

stoyan

unread,
Sep 2, 2010, 3:43:44 PM9/2/10
to w...@google.com, sche...@chromium.org, Chromium-dev, sat...@chromium.org
Correct, but having the "name" variable adds additional indirection when string is referenced from any code.
And adds 4 (8) bytes more to the data section. (not counting the relocation entry)


Mark Mentovai

unread,
Sep 2, 2010, 3:45:20 PM9/2/10
to sche...@chromium.org, Chromium-dev, sat...@chromium.org
Andrew Scherkus wrote:
> I just noticed the style guide recommends const char* [1]

The only relevant thing I see in there is advice to use char* at
namespace scope in preference to std::string. That shouldn’t be read
as expressing a preference between char* and char[] in any context. At
all.

> but I had always
> assumed we preferred const char[] based on its prevalence in *_switches.cc/h
> files:

I just went through this with Erik for http://crbug.com/49544.

Summary:

const char kCharacterConstant[] is OK, and is best in most cases.
const char* const kCharacterConstant is OK. (You can also spell this
char const* const.)
const char* kCharacterConstant probably doesn’t do what you want.

Each has valid uses.

Assuming you’ve got some character data that you want to make a
constant, you want either |const char kCharacterConstant[]| or |const
char* const kCharacterConstant|. People commonly write |const char*
kCharacterConstant|, but this isn’t really const enough, and it often
doesn’t do what you think it does. |const char* kCharacterConstant|
says “kCharacterConstant is a non-const pointer to const data” and
thus still allows kCharacterConstant (the pointer value) to be
modified by assignment. |const char* const kCharacterConstant| says
“kCharacterConstant is a const pointer to const data” and doesn’t
allow the pointer OR the data to be modified.

This was significant in the bug referenced above because the pointer’s
non-constness, when used in another global variable, resulted in the
creation of a run-time static initializer instead of compile-time
const data. Bad.

Given the choice between |const kCharacterConstant[]| and |const char*
const kCharacterConstant|, I personally have no preference—the right
one depends on the context—but the former probably matches the
intention more closely in more cases. The [] form gives you a handle
to the storage used for the actual character data, which means that
you can use things like sizeof and arraysize if you’re in the same
translation unit where kCharacterConstant is defined. You can
sometimes take advantage of that and write |const size_t
kCharacterConstantLen = arraysize(kCharacterConstant) - 1;|, giving
you a compile-time constant for the length too, instead of having to
use a run-time call to strlen.

I don’t consider |const char* const| to be “going crazy” in the sense
that the style guide advises against, although I’d probably feel
differently if there were another * or & with another const on there.

Marc-Antoine Ruel

unread,
Sep 2, 2010, 4:03:49 PM9/2/10
to ma...@chromium.org, sche...@chromium.org, Chromium-dev, sat...@chromium.org
The main reason I'm recommending a pointer is because I've seen a few times people using the array notation for local const string variables. That is the worst case since it means stack usage. The next worst case is using non-const global pointers since the compiler can't optimize the name out. Then the rest is really just a few bytes here and there.

M-A

Mark Mentovai

unread,
Sep 2, 2010, 4:19:34 PM9/2/10
to Marc-Antoine Ruel, sche...@chromium.org, Chromium-dev, sat...@chromium.org
Marc-Antoine Ruel wrote:
> The main reason I'm recommending a pointer is because I've seen a few times
> people using the array notation for local const string variables. That is
> the worst case since it means stack usage.

A local const string should be |static const char
kLocalCharacterConstant[]| or |const char* const
kLocalCharacterConstant| (static or not). |const char*
kLocalCharacterConstant| can still have its pointer value accidentally
modified, which I think is pretty bad, unless you actually want it to
be mutable.

Marc-Antoine Ruel

unread,
Sep 2, 2010, 4:28:32 PM9/2/10
to Mark Mentovai, sche...@chromium.org, Chromium-dev, sat...@chromium.org
local static arrays are first-execution-initialized on MSVC AFAIK. I'd need to confirm on latest compiler but when in doubt, I prefer the saner choice to not use static locals.

Mark Mentovai

unread,
Sep 2, 2010, 4:43:36 PM9/2/10
to Marc-Antoine Ruel, sche...@chromium.org, Chromium-dev, sat...@chromium.org
Marc-Antoine Ruel wrote:
> local static arrays are first-execution-initialized on MSVC AFAIK.

It would surprise me if MSVC needed to initialize these at runtime if
marked “static const”—that would seem to imply that it would also
elect to use a run-time static initializer for |const char
kCharacterConstant[]| at namespace scope too, instead of just loading
it as data.

> I'd need
> to confirm on latest compiler but when in doubt, I prefer the saner choice
> to not use static locals.

That’s cool. Like I said, I don’t really have a personal preference
and there’s a place for each of these, but if it’s spelled with a *
and it’s supposed to be immutable for real and not able to point to
something else, it ought to name “const” twice.

Reply all
Reply to author
Forward
0 new messages