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

const in C++

P: n/a
What are some of the fundamental differences
between const in C++ and const in C?

I know const in C does not mean 'constant'
but iirc const in C++ does. Additionally,
in C, one thinks of const as meaning 'read-only'.
There also exist oddities in C with
the use of const in association with pointer
objects and that such oddities do not exist
in C++. For example, const char **foo;

In C, the above is a pointer to type
"pointer to char read-only" and so
assignments like the following
cannot be made:
const char **foo;
char **baz;
foo = baz;

But in C++, I think I remember
reading that this works.

Any clarification welcomed.

--
conrad

Aug 11 '07 #1
Share this Question
Share on Google+
15 Replies


P: n/a
conrad wrote:
What are some of the fundamental differences
between const in C++ and const in C?
It works as one would expect in C++ and it's a bit broken in C?

In C, a const integer type isn't a compile time constant while in C++ it is.
>
In C, the above is a pointer to type
"pointer to char read-only" and so
assignments like the following
cannot be made:
const char **foo;
char **baz;
foo = baz;

But in C++, I think I remember
reading that this works.
In C, you could get away with this (I'm not sure if the compiler is
required to issue a diagnostic), in C++, it is an error.

--
Ian Collins.
Aug 11 '07 #2

P: n/a
conrad wrote:
>
In C, the above is a pointer to type
"pointer to char read-only" and so
assignments like the following
cannot be made:
const char **foo;
char **baz;
foo = baz;

But in C++, I think I remember
reading that this works.
Nope, it's the same in C and C++. Either what
you are reading is wrong or you misremember it.

You can't convert from char** to const char** because it's
not type safe.

Imagine this:

const char really_const = '?';

void f(const char*& x) {
x = &really_const; // valid: assignmetn of const
char* to const char*(reference).
}

int main() {
char* y;

f(y); // imagine the compiler let you do this (it
shouldn't).

*y = '!'; // BOOM! Just modified a really_const

}

[ Se
Aug 12 '07 #3

P: n/a
On Aug 12, 12:57 am, conrad <con...@lawyer.comwrote:
What are some of the fundamental differences
between const in C++ and const in C?
There aren't any fundamental differences, just some small
details.
I know const in C does not mean 'constant'
but iirc const in C++ does.
Formally, the rules are the same: attempting to modify a const
object is undefined behavior. The difference you're probably
thinking about is that in C++, a const variable initialized with
an integral constant expression can itself be used as an
integral constant expression; this is not the case in C.
Additionally,
in C, one thinks of const as meaning 'read-only'.
In C++ too.
There also exist oddities in C with
the use of const in association with pointer
objects and that such oddities do not exist
in C++. For example, const char **foo;
In C, the above is a pointer to type
"pointer to char read-only" and so
assignments like the following
cannot be made:
const char **foo;
char **baz;
foo = baz;
But in C++, I think I remember
reading that this works.
Nope.

You're probably thinking of something like:

char const* const* p ;
char ** q ;
p = q ;

This works in C++, but not in C (at least, not in C 90). The
reason, in this case, was an oversight in the C90 standard;
originally, both worked, but someone spotted the loophole Ron
pointed out, very late in the standardization of C90, and text
was added to close it. After the promulgation of C90, it was
realized that the text was actually too restrictive, that it
also forbid something like my example, above, although there is
no violation of const safety here. So the authors of the C++
standard rewrote the rule to allow the cases which didn't cause
problems. (Apparently, the authors of C99 didn't feel it
necessary to adopt this change.)

--
James Kanze (GABI Software) email:james.ka...@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

Aug 12 '07 #4

P: n/a
James Kanze wrote:
On Aug 12, 12:57 am, conrad <con...@lawyer.comwrote:
>What are some of the fundamental differences
between const in C++ and const in C?

There aren't any fundamental differences, just some small
details.
This is valid C++ and invalid C:

const int s = 10;
int table[s];

Wouldn't you call that a "fundamental" difference?
Aug 12 '07 #5

P: n/a
On Aug 12, 6:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
>
This is valid C++ and invalid C:

const int s = 10;
int table[s];

Wouldn't you call that a "fundamental" difference?
Get with the times! C99 is only what, 8 years old now? It is perfectly
valid 'C'!
Aug 12 '07 #6

P: n/a
On Aug 12, 7:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
James Kanze wrote:
On Aug 12, 12:57 am, conrad <con...@lawyer.comwrote:
What are some of the fundamental differences
between const in C++ and const in C?
There aren't any fundamental differences, just some small
details.
This is valid C++ and invalid C:
const int s = 10;
int table[s];
Wouldn't you call that a "fundamental" difference?
Not with const per se. It only affects integral constant
expressions---one particular type and use of constants. And
it's really only a small part of that.

--
James Kanze (GABI Software) email:james.ka...@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

Aug 13 '07 #7

P: n/a
On Aug 12, 8:57 pm, Pete C <5gv7rq...@sneakemail.comwrote:
On Aug 12, 6:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
This is valid C++ and invalid C:
const int s = 10;
int table[s];
Wouldn't you call that a "fundamental" difference?
Get with the times! C99 is only what, 8 years old now? It is perfectly
valid 'C'!
It's not valid C, even C99.

--
James Kanze (GABI Software) email:james.ka...@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
Aug 13 '07 #8

P: n/a
On Aug 13, 1:16 am, James Kanze <james.ka...@gmail.comwrote:
On Aug 12, 8:57 pm, Pete C <5gv7rq...@sneakemail.comwrote:
On Aug 12, 6:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
This is valid C++ and invalid C:
const int s = 10;
int table[s];
Wouldn't you call that a "fundamental" difference?
Get with the times! C99 is only what, 8 years old now? It is perfectly
valid 'C'!

It's not valid C, even C99.
Well, no, that's incorrect. It is valid C99 because that is considered
a variable-length array; however, it does not factor into the argument
about constants, because 's' is still not a compile-time constant.

Aug 13 '07 #9

P: n/a
James Kanze wrote:
On Aug 12, 8:57 pm, Pete C <5gv7rq...@sneakemail.comwrote:
>On Aug 12, 6:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
>> This is valid C++ and invalid C:
>>const int s = 10;
int table[s];
>> Wouldn't you call that a "fundamental" difference?
>Get with the times! C99 is only what, 8 years old now? It is perfectly
valid 'C'!

It's not valid C, even C99.
Says who?

It's one one of those odd cases where something is legal C and C++,
appears to do the same but in fact is a normal array in C++ and a
Variable Length Array in C.

--
Ian Collins.
Aug 13 '07 #10

P: n/a
On Aug 13, 8:47 am, "Justin.SpahrSumm...@gmail.com"
<Justin.SpahrSumm...@gmail.comwrote:
On Aug 13, 1:16 am, James Kanze <james.ka...@gmail.comwrote:
On Aug 12, 8:57 pm, Pete C <5gv7rq...@sneakemail.comwrote:
On Aug 12, 6:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
This is valid C++ and invalid C:
const int s = 10;
int table[s];
Wouldn't you call that a "fundamental" difference?
Get with the times! C99 is only what, 8 years old now? It is perfectly
valid 'C'!
It's not valid C, even C99.
Well, no, that's incorrect. It is valid C99 because that is
considered a variable-length array; however, it does not
factor into the argument about constants, because 's' is still
not a compile-time constant.
Except that variable length arrays aren't legal for variables
with static lifetime, as is the case here. They're only legal
for local variables.

--
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

Aug 13 '07 #11

P: n/a
James Kanze wrote:
On Aug 13, 8:47 am, "Justin.SpahrSumm...@gmail.com"
<Justin.SpahrSumm...@gmail.comwrote:
>On Aug 13, 1:16 am, James Kanze <james.ka...@gmail.comwrote:
>>On Aug 12, 8:57 pm, Pete C <5gv7rq...@sneakemail.comwrote:
>>>On Aug 12, 6:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
This is valid C++ and invalid C:
const int s = 10;
int table[s];
Wouldn't you call that a "fundamental" difference?
Get with the times! C99 is only what, 8 years old now? It is perfectly
valid 'C'!
>>It's not valid C, even C99.
>Well, no, that's incorrect. It is valid C99 because that is
considered a variable-length array; however, it does not
factor into the argument about constants, because 's' is still
not a compile-time constant.

Except that variable length arrays aren't legal for variables
with static lifetime, as is the case here. They're only legal
for local variables.
True, but there wasn't enough context to deduce whether this snippet was
from a function or global scope.

So we where all right :)

--
Ian Collins.
Aug 13 '07 #12

P: n/a
On Aug 13, 9:06 am, Ian Collins <ian-n...@hotmail.comwrote:
James Kanze wrote:
On Aug 12, 8:57 pm, Pete C <5gv7rq...@sneakemail.comwrote:
On Aug 12, 6:57 pm, Juha Nieminen <nos...@thanks.invalidwrote:
> This is valid C++ and invalid C:
>const int s = 10;
int table[s];
> Wouldn't you call that a "fundamental" difference?
Get with the times! C99 is only what, 8 years old now? It is perfectly
valid 'C'!
It's not valid C, even C99.
Says who?
ISO 9899:1999.
It's one one of those odd cases where something is legal C and C++,
appears to do the same but in fact is a normal array in C++ and a
Variable Length Array in C.
Except that ISO 9899:1999 places some restrictions on where you
can have a variable length array. In particular, §6.7.5.2/2:

-- Only an ordinary identifier (as defined in 6.2.3) with
both block scope or function prototype scope and no
linkage shall have a variably modified type. If an
identifier is declared to be an object with static
storage duration, it shall not have a variable length
array type.

In C++, of course, we also have variable length arrays, but the
declaration syntax is different (std::vector), and they are
legal anywhere, not just as local variables without linkage.

--
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

Aug 13 '07 #13

P: n/a
Ian Collins wrote:
It works as one would expect in C++
Well, depends on what you expect. One might expect a const foo* to be a
pointer to a const foo, but actually it doesn't imply anything about the
constness of the foo. This has always bothered me, especially since a real
pointer-to-const-foo would enable more optimizations. I kind of wish foo
const* had been used for the read-only pointer, and const foo* for the
pointer to a const object. Though I suppose this breaks for pointers to
pointers, since you can't distinguish foo *const * from foo * const*. In
summary, C's type syntax sucks.

-- Ben
Aug 26 '07 #14

P: n/a
Ben Rudiak-Gould wrote:
Ian Collins wrote:
>It works as one would expect in C++

Well, depends on what you expect. One might expect a const foo* to be a
pointer to a const foo, but actually it doesn't imply anything about the
constness of the foo.
From the perspective of the pointer it does. One could also argue that
the pointer may not even point to a foo, it could be cast from some
random address.
--
Ian Collins.
Aug 26 '07 #15

P: n/a
Ian Collins wrote:
From the perspective of the pointer it does. One could also argue that
the pointer may not even point to a foo, it could be cast from some
random address.
There's a difference. An (int *) might not point to an int, but the standard
allows the implementation to assume that it does whenever it's dereferenced.
A (const int) might not be constant, but the implementation is allowed to
cache it as though it were. But the standard forbids an implementation from
assuming that a (const int *) points to a const int. For example, in code like

void f(const int * p) {
for (...) {
... do something with *p ...
function_with_an_inaccessible_definition();
}
}

the implementation is forbidden from caching *p across loop iterations.

I think the type syntax could have been defined such that (expr)* always
meant a pointer to something of type expr, if it had a second object
modifier meaning "not const". A (mutable int *) would point to an int that
definitely wasn't const, like the current (int *); a (const int *) would
point to an int that definitely was const (hence cacheable); and a plain
(int *) would point to something of unknown constness, like the current
(const int *). Or there could have been a different syntax for read-only
pointers and references, like (int *=) and (int &=), with const used only to
indicate constness.

I suppose it's a moot point now that restricted pointers are finally
starting to catch on. The restrict qualifier gets you the same optimization
benefits and a lot more. Still, it would have been cleaner.

-- Ben
Aug 27 '07 #16

This discussion thread is closed

Replies have been disabled for this discussion.