Hellp with type promotion

M

manochavishal

HI,
I read that every char in expression is promoted to int.

So as function arguments are expressions so type promotion should take
place for arguments passed to function.

so

*****
int main(void)
{
char c = 'C';
test(c);

return 0;
}

void test(char c)
{
printf("Size of char is %d",sizeof(c));

}
*******


should print -Size of char is 4 - as the char c is promoted to type
int.

But it prints 1

Why??

Cheers
Vishal
 
R

Ravi Uday

HI,
I read that every char in expression is promoted to int.

So as function arguments are expressions so type promotion should take
place for arguments passed to function.

so

*****
int main(void)
{
char c = 'C';
test(c);

return 0;
}

void test(char c)
{
printf("Size of char is %d",sizeof(c));

sizeof - The sizeof operator yields the size (in bytes) of its operand,
so in your case the operand is c which is of type 'char'
and on your system size of char is 1 so you get 1 when you print that !
}
*******


should print -Size of char is 4 - as the char c is promoted to type
int.

No it doesnt

- ravi
 
M

manochavishal

Hi,

it does promote to int type.

If we dont explicitly declare the function prototype, the function
argument character is promoted to int.



void test();
int main(void)
{


int n;
char c = 'C';
test(c);

printf("\nsize in main %d",sizeof(c));

return 0;

}
void test(c)
{
printf("size in func %d",sizeof(c));
}


This prints:

size in func 4
size in main 1

So if we dont tell compiler explicitly in the prototype the type of
arguments they are promoted.

Great!!

Cheers
Vishal.
 
R

Richard Bos

I read that every char in expression is promoted to int.
Yes.

So as function arguments are expressions so type promotion should take
place for arguments passed to function.

No. This is only true for old-style declarations, a function without a
declaration, or the variable arguments of a variadic function.

Richard
 
R

Robin Haigh

Hi,

it does promote to int type.

If we dont explicitly declare the function prototype, the function
argument character is promoted to int.



void test();
int main(void)
{


int n;
char c = 'C';
test(c);

printf("\nsize in main %d",sizeof(c));

return 0;

}
void test(c)
{
printf("size in func %d",sizeof(c));
}


This prints:

size in func 4
size in main 1

So if we dont tell compiler explicitly in the prototype the type of
arguments they are promoted.


But here's the odd thing. If you change the call

test(c);

to

test();

so that you don't pass an argument at all, you still get the same output
 
M

Martin Ambuhl

HI,
I read that every char in expression is promoted to int.
So as function arguments are expressions so type promotion should take
place for arguments passed to function.
so

*****
int main(void)
{
char c = 'C';
test(c);

return 0;
}

void test(char c)
{
printf("Size of char is %d",sizeof(c));

}
*******


should print -Size of char is 4 - as the char c is promoted to type
int.

But it prints 1

Why??

The real question is why you either
1) have your diagnostics turned off or
2) are ignoring them.
These are the diagnostics gcc produces for your code:

a.c: In function 'main':
a.c:4: warning: implicit declaration of function 'test'
a.c: At top level:
a.c:10: warning: conflicting types for 'test'
a.c:4: warning: previous implicit declaration of 'test' was here
a.c: In function 'test':
a.c:11: warning: implicit declaration of function 'printf'
a.c:11: warning: incompatible implicit declaration of built-in function
'printf'
a.c:11: warning: format '%d' expects type 'int', but argument 2 has type
'long unsigned int'
 
A

A. Sinan Unur

....
....
But here's the odd thing. If you change the call

test(c);

to

test();

so that you don't pass an argument at all, you still get the same
output

How is that odd? (Except that the code looks like it is from the 80s).

You have circumvented the prototype system. When func is called, it is
set up to receive one int argument. The value might be crap, but that
doesn't really matter because sizeof does not evaluate its operand.

Of course, IMHO, anyone who writes code like this in this day and age
deserves whatever they get.

Sinan
 
D

Default User

int main(void)
{
char c = 'C';
test(c);

return 0;
}

void test(char c)
{
printf("Size of char is %d",sizeof(c));

}

1. This code is not legal. You don't have a declaration for test, and
the definition is different than the default declaration you would get
with a pre-C99 compiler. Also, printf() is a variadic function a
requires a prototype. The best way is to include <stdio.h>

2. Even if there were a legal implicit declaration or an old-style
declaration, that wouldn't matter. Except for variable-length arrays,
sizeof is performed at compile time. What the arguments get promoted to
at run-time have no bearing on what's printed there. It will be
sizeof(char), which is guaranteed to be 1, always.



Brian
 
D

Default User

Hi,

it does promote to int type.

If we dont explicitly declare the function prototype, the function
argument character is promoted to int.



void test();
int main(void)
{


int n;
char c = 'C';
test(c);

printf("\nsize in main %d",sizeof(c));

return 0;

}
void test(c)
{
printf("size in func %d",sizeof(c));
}


This prints:

size in func 4
size in main 1

So if we dont tell compiler explicitly in the prototype the type of
arguments they are promoted.

Has nothing to do with promotion. You didn't give c a type in the
definition of test(). Therefore the implementation provided one for
you. The equivalent definition was:

void test(c)
int c;
{
}




So you got sizeof(int).



Brian
 
K

Keith Thompson

I read that every char in expression is promoted to int.

So as function arguments are expressions so type promotion should take
place for arguments passed to function.

so

*****
int main(void)
{
char c = 'C';
test(c);

return 0;
}

void test(char c)
{
printf("Size of char is %d",sizeof(c));

}
*******


should print -Size of char is 4 - as the char c is promoted to type
int.

But it prints 1

There are several problems with your program:
Calling test() with no visible declaration.
Missing "#include <stdio.h>".
No newline at the end of your output.
Incompatible type for "%d" format (it expects an int; you gave it
a size_t).

Leaving that aside, the parameter "c" within your "test" function is
effectively a local variable of type char. sizeof(c) yields the size
of that variable, which is 1 byte by definition.

There are a number of rules about when integer promotions and default
argument promotions are applied (and I actually don't know all the
rules myself). But applying sizeof to a variable doesn't involve any
promotions; it simply yields the size of the variable.

The fact that the variable happens to be a parameter is irrelevant.
On the function call, the value of the argument (the variable "c" in
main) is used to initialize the parameter object (the parameter "c" in
test(); this would be easier if they had different names). But the
value assigned to it doesn't affect its size.
 
D

Dave Thompson

HI,
I read that every char in expression is promoted to int.
Not quite all. As the operand to any computational operator, yes. Not
as a full-expression (though that's useless) or an operand of sizeof
or & (address) or of the comma operator; and not necessarily as the
RHS of an assignment, or passing to a prototyped function or returning
from (any) function which are both as-if assignment.

Also note this applies only to the value of a char _object_ (variable)
or a value (number) cast to char. A character constant aka literal
like 'x' has type int _already_, before any promotion or conversion
-- in C <OT> but not in C++. </>

- David.Thompson1 at worldnet.att.net
 

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

Forum statistics

Threads
474,176
Messages
2,570,949
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top