#define vs const declaration

S

subramanian100in

Suppose I have #included <stdint.h>

#define MAX_LINE_SIZE SIZE_MAX

or

const size_t maxLineLength = SIZE_MAX ;

Between the above #define and const declaration, which should be
preferred and why ?
 
S

santosh

Suppose I have #included <stdint.h>

#define MAX_LINE_SIZE SIZE_MAX

or

const size_t maxLineLength = SIZE_MAX ;

Between the above #define and const declaration, which should be
preferred and why ?

There's no universal answer. Both have some advantages and
disadvantages. Depending on your exact usage of the constant, one of
the methods can be chosen.

The preprocessor based method offers more flexibility at the cost of
loss of type safety and scope. Preprocessor symbols are file scope and
thus can be inadvertently misused. However their big advantage is that
they're available at compile time and hence can be used for things
like macros and conditional compilation. const qualified objects only
exist at runtime. However their use can be better checked by the
compiler.
 
S

subramanian100in

There's no universal answer. Both have some advantages and
disadvantages. Depending on your exact usage of the constant, one of
the methods can be chosen.

The preprocessor based method offers more flexibility at the cost of
loss of type safety and scope. Preprocessor symbols are file scope and
thus can be inadvertently misused. However their big advantage is that
they're available at compile time and hence can be used for things
like macros and conditional compilation. const qualified objects only
exist at runtime. However their use can be better checked by the
compiler.

I understand your point.

If a const variable is used, it will be visible to the debugger. Can
this
be treated as an advantage of a const decalration when both are
allowed
for a particular situation.
 
S

santosh

I understand your point.

If a const variable is used, it will be visible to the debugger. Can this
be treated as an advantage of a const decalration when both are
allowed for a particular situation.

Yes.

One more thing. A const object is prone to inadvertent modification,
which leads to undefined behaviour. A preprocessor constant cannot be
modified, since it's not an lvalue.
 
S

santosh

santosh said:
Yes.

One more thing. A const object is prone to inadvertent modification,
[ ... ]

The word 'prone' probably conveys it's meaning in a stronger form than
I intended.
 
S

subramanian100in

I am unable to understand this. If we try to modify a const object
inadvertantly, won't the compiler give diagnostic ?
 
S

santosh

I am unable to understand this. If we try to modify a const object
inadvertantly, won't the compiler give diagnostic ?

Obviously the compiler will emit a diagnostic, but it's still
possible. The other case is not possible.
 
C

CBFalconer

I am unable to understand this. If we try to modify a const object
inadvertantly, won't the compiler give diagnostic ?

It can be accidentally modified, for example by a buffer overrun or
a wild pointer.

You can get the advantage of debugger visibility by name and a
#define by using:

enum {MAXWHATEVER = 12345};

after which you can use MAXWHATEVER just as if it had been
#defined. The value needs to be an integer.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
C

christian.bau

Suppose I have #included <stdint.h>

#define MAX_LINE_SIZE SIZE_MAX

or

const size_t maxLineLength = SIZE_MAX ;

Between the above #define and const declaration, which should be
preferred and why ?

I usually use

enum { kMaxLineLength = SIZE_MAX };
 
S

Servé Laurijssen

I am unable to understand this. If we try to modify a const object
inadvertantly, won't the compiler give diagnostic ?

Not always

For instance, this compiles
char *s = "a";
s[0] = 'b';

while s is actually const.

But also the "constness" of an object can get lost somewhere in the jungle
of function calls because somebody had to cast it away to be able to use a
function that expects a non const. This cant happen when a macro is used
because the following is not possible.

#define VAL 2

VAL = 3;

I think thats what santosh meant
 
B

Ben Pfaff

Servé Laurijssen said:
For instance, this compiles
char *s = "a";
s[0] = 'b';

while s is actually const.

I'm sure that experienced C programmers will all know what you
mean here, but I think it's worth noting a couple of things for
the novices. First, s is modifiable here; it is the string
literal that s points into that may not be modified. Second, the
characters in the string literal are not actually
const-qualified; rather, they are just non-modifiable.
 
I

Ian Collins

Servé Laurijssen said:
I am unable to understand this. If we try to modify a const object
inadvertantly, won't the compiler give diagnostic ?

Not always

For instance, this compiles
char *s = "a";
s[0] = 'b';

while s is actually const.

But also the "constness" of an object can get lost somewhere in the jungle
of function calls because somebody had to cast it away to be able to use a
function that expects a non const. This cant happen when a macro is used
because the following is not possible.

#define VAL 2

VAL = 3;
But in the case you cite, the fact that a parameter started life as a
macro will be lost by the time it becomes a function parameter. The
only case that comes to mind is where a parameter is passed by address
and you can't take the address of a macro constant.
 
W

websnarf

I am unable to understand this. If we try to modify a const object
inadvertantly, won't the compiler give diagnostic ?

Not always

For instance, this compiles
char *s = "a";
s[0] = 'b';

while s is actually const.

s is not const. s is currently pointing at something which is not
legally modifiable. It is perfectly legal to point s at something
else and modify stuff through the s pointer.
 
K

Keith Thompson

CBFalconer said:
It can be accidentally modified, for example by a buffer overrun or
a wild pointer.

You can get the advantage of debugger visibility by name and a
#define by using:

enum {MAXWHATEVER = 12345};

after which you can use MAXWHATEVER just as if it had been
#defined. The value needs to be an integer.

And, in fact, it needs to be within the range of type int.
 
K

Keith Thompson

Suppose I have #included <stdint.h>

#define MAX_LINE_SIZE SIZE_MAX

or

const size_t maxLineLength = SIZE_MAX ;

Between the above #define and const declaration, which should be
preferred and why ?

SIZE_MAX is an awfully big line length.
 
B

Ben Pfaff

CBFalconer said:
You can get the advantage of debugger visibility by name and a
#define by using:

enum {MAXWHATEVER = 12345};

after which you can use MAXWHATEVER just as if it had been
#defined. The value needs to be an integer.

You can often get better debugger visibility by giving the
enumeration type a name and then declaring objects that take the
enumeration's value to have that type. Then the debugger is more
likely able to tell you the object's value by name, rather than
by value.
 
B

Ben Pfaff

Suppose I have #included <stdint.h>

#define MAX_LINE_SIZE SIZE_MAX

or

const size_t maxLineLength = SIZE_MAX ;

Between the above #define and const declaration, which should be
preferred and why ?

I'd probably prefer the former, because it can be used as a
compile-time constant. (However, that's most useful when you can
declare an array with that many elements; declaring an array to
have SIZE_MAX elements is unwise.)
 
B

Bill Pursell

Obviously the compiler will emit a diagnostic, but it's still
possible. The other case is not possible.


#include <stdio.h>
#define MAX 243

int
main(void)
{
printf("MAX = %d\n", MAX);
#undef MAX
#define MAX 18
printf("MAX = %d\n", MAX);

return 0;
}
 

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,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top