what is the type of a #define const number

M

miaohua1982

the code is as follows:

#include<stdio.h>
int arr[]={1,2,3,4,5,6,7};
#define size (sizeof(arr)/sizeof(arr[0]))
int main()
{
int index = -1;
int x = 0;
int t;
if( index < size - 1 )
x = arr[index+1];
printf("%d",x);
return 0;
}

then the value of x is 0, not 1. Maybe the type of "index" is promoted
to unsigned int ?so the type of "size" is unsigned int?How can I
decide the type of a const number by #define macro?Is there anyone
can tell me?
Thank you!
 
V

Victor Bazarov

the code is as follows:

#include<stdio.h>
int arr[]={1,2,3,4,5,6,7};
#define size (sizeof(arr)/sizeof(arr[0]))
int main()
{
int index = -1;
int x = 0;
int t;
if( index < size - 1 )
x = arr[index+1];
printf("%d",x);
return 0;
}

then the value of x is 0, not 1. Maybe the type of "index" is promoted
to unsigned int ?so the type of "size" is unsigned int?

Actually, yes. 'sizeof' "returns" size_t, which is unsigned in most
implementations. So, promoted to 'size_t', not necessarily unsigned int.
"size" gets replaced with "(sizeof(arr)/sizeof(arr[0]))", so by the time
there are any types in the program, there is no "size"...
How can I
decide the type of a const number by #define macro?Is there anyone
can tell me?

Any macro just substitutes one expression with another. You need to
see what your code looks like after preprocessing to understand what
your expression looks like and what type it has.

V
 
Y

yashwant pinge

the code is as follows:
#include<stdio.h>
int arr[]={1,2,3,4,5,6,7};
#define size (sizeof(arr)/sizeof(arr[0]))
int main()
{
int index = -1;
int x = 0;
int t;
if( index < size - 1 )
x = arr[index+1];
printf("%d",x);
return 0;
}
then the value of x is 0, not 1. Maybe the type of "index" is promoted
to unsigned int ?so the type of "size" is unsigned int?

Actually, yes. 'sizeof' "returns" size_t, which is unsigned in most
implementations. So, promoted to 'size_t', not necessarily unsigned int.
"size" gets replaced with "(sizeof(arr)/sizeof(arr[0]))", so by the time
there are any types in the program, there is no "size"...
How can I
decide the type of a const number by #define macro?Is there anyone
can tell me?

Any macro just substitutes one expression with another. You need to
see what your code looks like after preprocessing to understand what
your expression looks like and what type it has.

V

The disadvantage of macro is that it doesnot follow the strict type
checking

To run the code, write the statement as

#define size (int)(sizeof(arr)/sizeof(arr[0]))
OR
if( index < int(size - 1) )
 
V

Victor Bazarov

yashwant said:
the code is as follows:
#include<stdio.h>
int arr[]={1,2,3,4,5,6,7};
#define size (sizeof(arr)/sizeof(arr[0]))
int main()
{
int index = -1;
int x = 0;
int t;
if( index < size - 1 )
x = arr[index+1];
printf("%d",x);
return 0;
}
then the value of x is 0, not 1. Maybe the type of "index" is
promoted to unsigned int ?so the type of "size" is unsigned int?

Actually, yes. 'sizeof' "returns" size_t, which is unsigned in most
implementations. So, promoted to 'size_t', not necessarily unsigned
int. "size" gets replaced with "(sizeof(arr)/sizeof(arr[0]))", so by
the time there are any types in the program, there is no "size"...
How can I
decide the type of a const number by #define macro?Is there anyone
can tell me?

Any macro just substitutes one expression with another. You need to
see what your code looks like after preprocessing to understand what
your expression looks like and what type it has.

V

The disadvantage of macro is that it doesnot follow the strict type
checking

How does type *checking* would play here? '(sizeof(a)/sizeof(b))'
expression has a very specific type.
To run the code, write the statement as

#define size (int)(sizeof(arr)/sizeof(arr[0]))
OR
if( index < int(size - 1) )

That's dangerous because 'size_t' and 'int' are not necessarily the
same size, which means not all values of 'size_t' can be represented
by an 'int'.

Why not simply do

const int size = sizeof(arr) / sizeof(arr[0]);

and be rid of the macro altogether?

V
 
G

Gavin Deane

yashwant said:
#define size (int)(sizeof(arr)/sizeof(arr[0]))
OR
if( index < int(size - 1) )

That's dangerous because 'size_t' and 'int' are not necessarily the
same size, which means not all values of 'size_t' can be represented
by an 'int'.

Why not simply do

const int size = sizeof(arr) / sizeof(arr[0]);

and be rid of the macro altogether?

Did you mean

const size_t size = sizeof(arr) / sizeof(arr[0]);

or did I miss something?

Gavin Deane
 
V

Victor Bazarov

Gavin said:
yashwant said:
#define size (int)(sizeof(arr)/sizeof(arr[0]))
OR
if( index < int(size - 1) )

That's dangerous because 'size_t' and 'int' are not necessarily the
same size, which means not all values of 'size_t' can be represented
by an 'int'.

Why not simply do

const int size = sizeof(arr) / sizeof(arr[0]);

and be rid of the macro altogether?

Did you mean

const size_t size = sizeof(arr) / sizeof(arr[0]);

or did I miss something?

I did mean 'int' because that's how the OP wanted this value to be
defined. The problem the OP described was due to the fact that some
other value was promoted to the type of size (instead of keeping it
the same). Begs the question why the language doesn't have some kind
of "protection against standard conversions/promotions". It could be
beneficial [in rare cases] to have (WARNING: not C++!)

auto size = sizeof(arr) / sizeof(arr[0]); // 'size' gets its type
// from the expression
....
int protected blah; // "protected" from promotions/conversions
....
if (blah < size) // requires promoting 'blah', flagged as error
....

V
 
R

Ron Natalie

Victor said:
Actually, yes. 'sizeof' "returns" size_t, which is unsigned in most
implementations

It must be some unsigned integral type in ALL implementations.
 
P

Pete Becker

yashwant said:
The disadvantage of macro is that it doesnot follow the strict type
checking

A macro that defines an integral constant has a well defined type, just
as any other form of integral constant does.
To run the code, write the statement as

#define size (int)(sizeof(arr)/sizeof(arr[0]))
OR
if( index < int(size - 1) )

That has nothing to do with the fact that size is a macro. It's simply
because the type of size is size_t. The same problem would occur if size
were explicitly defined to have type size_t:

size_t size = sizeof(arr)/sizeof(arr[0]);

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 

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,444
Messages
2,571,709
Members
48,796
Latest member
Greg L.
Top