When to use const modifier?

  • Thread starter Leonardo Korndorfer
  • Start date
W

Walter Roberson

On 3 Jun 2008 at 14:03, Walter Roberson wrote:
I find it pretty amazing that you and Sossman, who are appalled if
people don't keep at the front of their mind that "long unsigned int
long" is a synonym for "unsigned long long", or fail to account for the
behavior of their code on a machine with no stack where fopen always
returns NULL, and generally seem content to waste hours of your time
pouring over the pointless minutiae of the dustier corners of the ANSI
Bible, should be so reluctant to figure out what const means.

I've read the Standard about what it means, but since after reading
the Standard, it -appears- to me to be mostly a waste of time,
I can't seem to bring myself to Drink The Cool-Aid quite yet.

Perhaps I should phrase the matter a different way:

Is there any conforming program that uses 'const' which have a
different output (aside from timing) if all of the 'const' were
removed from the program?
 
K

Keith Thompson

I've read the Standard about what it means, but since after reading
the Standard, it -appears- to me to be mostly a waste of time,
I can't seem to bring myself to Drink The Cool-Aid quite yet.

Perhaps I should phrase the matter a different way:

Is there any conforming program that uses 'const' which have a
different output (aside from timing) if all of the 'const' were
removed from the program?

I believe the answer to that is "no" (ignoring arbitrary changes in
unspecified behavior).

However, there are plenty of *incorrect* programs that are likely to
compile with no diagnostics, in which judicious use of "const" can get
the compiler to detect the error. For example:

/* const */ char *s = "hello";
s[0] = 'H';

On the other hand, adding "const" here means that you can't pass s as
an argument to a function that expects a (non-const) char*. On the
other other hand, if you're going to be passing s to such a function,
the parameter probably should have been declared "const" anyway. (See
"const poisoning".)

(If I were designing a new language from scratch, I'd probably make
const (or equivalent) the default for declared variables. Given
sufficiently flexible initialization, I suspect, with no real
evidence, that a lot of objects aren't actually modified after their
initialization. If you want to be able to modify an object later on,
declare it with a "var" keyword or some other special syntax.
Declaring an object with neither "var" nor an initializer would be an
error. Possibly nobody but me would want to use such a language.)
 
F

Flash Gordon

Walter Roberson wrote, On 03/06/08 19:03:

Perhaps I should phrase the matter a different way:

Is there any conforming program that uses 'const' which have a
different output (aside from timing) if all of the 'const' were
removed from the program?

No. However there are programs with required diagnostics where the
required diagnostic will go away if you get rid of the const leaving you
with undiagnosed undefined behaviour.

markg@brenda:~$ cat t.c
int main(void)
{
/*const*/ char *fred="blogs";
*fred = 'B';
return 0;
}
markg@brenda:~$ gcc -ansi -pedantic -Wall -Wextra t.c
markg@brenda:~$ ./a.out
Segmentation fault
markg@brenda:~$

Uncomment the const and the program will not compile under gcc and under
*any* conforming compiler you will get some form of diagnostic.
 
T

Tomás Ó hÉilidhe

So, I've come to one simple conclusion:
One should use const when the content won't be modified anywhere after
initialization, and if it will be (and I say that because in "const
char*" case my compiler doesn't warn about changin' it), just don't
use "const".


Const is the default for me. If something's non-const then it's an
exception. In fact, you could mimick my way of programming simply by
doing the following:

1: Make everything const
2: Try to compile
3: If you get compile errors, remove the offending const's
 
H

Harald van Dijk

Is there any conforming program that uses 'const' which have a different
output (aside from timing) if all of the 'const' were removed from the
program?

#include <assert.h>
int main(void) {
assert((const char) 0 == 1);
}

:)
 
W

Walter Roberson

Walter Roberson wrote:
As long as you specified ignoring the timing, I believe the answer
is no. However the 'const' has the great advantage of catching
various user errors, and improving the code optimization.

In reading your response, I thought of a possibility:

If a program uses const, does that give the compiler any liberties
for optimization that would not be present in the const-less
version of the same program? If Yes, then we directly have different
semantics for the two programs. If No, then is it plausible that
a compiler might choose to employ one of the optimization
liberties that it -already- has, in a different way for a program
with 'const' as compared to the one without? If so, then the answer
to the question I posed could be "There are programs with const
in them that compiler XYZ version PQR compiles to a -different-
but still legitimate C program than XYZ version PQR compiles the
non-const version to."

I'm thinking vaguely of things like constant folding or places where
the order of operations is not nailed down (and strapped in,
embedded in cement and tied with "Police Line -- Do Not Cross" tape),
so that the outputs might be different due to round-off differences.
Of course optimizers routinely violate the virtual machine semantics,
but for the purpose of this discussion, assume that user has not
granted the compiler permission to violate the virtual machine semantics.
 
H

Harald van Dijk

If a program uses const, does that give the compiler any liberties for
optimization that would not be present in the const-less version of
the same program? [...]
I'm thinking vaguely of things like constant folding [...]

Sure, and as a result, the value of &(const int){0} == &(const int){0} is
unspecified, but that of &(int){0} == &(int){0} is guaranteed to be 0.
 
W

Walter Roberson

#include <assert.h>
int main(void) {
assert((const char) 0 == 1);
}

I gather you are pointing out that the assertion failed message will
contain the string 'const' in one case, but not in the 'other' ?
True, that would be different output. And presumably the same sort
of technique could be used in other stringifications -- e.g.,
the string length of a stringified argument containing const would
be different than if the const were present.

Tricky ;-)
 
K

Keith Thompson

If a program uses const, does that give the compiler any liberties
for optimization that would not be present in the const-less
version of the same program?
[...]

I believe the answer, to a first approximation, is theoretically no,
but practically yes (assuming both versions are correct).

For example consider this:

void foo(void)
{
/* const */ int x = 42;
/* a whole bunch of code */
printf("x = %d\n", x);
}

With the "const", the compiler is free to assume that x is equal to
42, and to replace the printf call with puts("x = 42"). Without the
"const", the compiler can't necessarily be sure that the "whole bunch
of code" doesn't modify the value of x, so it potentially needs to
generate code to re-load its value and pass it to printf. But if, as
we assumed, the program is correct with or without const, then the
"whole bunch of code" in fact *doesn't* modify x, and in principle the
compiler should be able to figure this out (in cases that aren't
isomorphic to the halting problem).

"const" is a way of telling the compiler something that you, the
programmer, already know, and that the compiler might or might not
have been able to figure out for itself.
 
I

Ian Collins

santosh said:
Even if so, I don't think restrict is used all that
frequently in C code. I have hardly ever seen it in code that I have
dealt with. It probably isn't a priority matter for Eric.
I assume from the above you don't work on a POSIX platform. POSIX APIs
make extensive use of restrict.
 
W

Walter Roberson

Ian Collins said:
I assume from the above you don't work on a POSIX platform. POSIX APIs
make extensive use of restrict.

Not in POSIX.1-1990 they don't! And presumably not in any other
POSIX.* from before 1999.
 
I

Ian Collins

Walter said:
Not in POSIX.1-1990 they don't! And presumably not in any other
POSIX.* from before 1999.

A modern POSIX system will have the C99 standard library interface.
 
S

santosh

Ian said:
I assume from the above you don't work on a POSIX platform. POSIX
APIs make extensive use of restrict.

I was talking about applications that I have been involved with. They
were both Windows as well as POSIX based, but I don't really recall
seeing restrict used. I suspect that the situation is different for
system and library code. The code for most large systems go back way
before 1999, and unless performance sucks, I don't see how extensive
addition of restrict would be sanctioned.

The problem with restrict is that it is too easy to use it improperly.
Frankly speaking most of the C programmers I have worked with were not
even aware of restrict. Unlike misuse of const, there would likely be
no helpful diagnostic from the compiler, leading to subtly broken
programs.
 

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
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top