3

I learned from ----As to when default promotions kick in: default argument promotions are used exactly when the expected type of the argument is unknown, which is to say when there's no prototype or when the argument is variadic.

But an example confusing me is:

void func(char a, char b)
{
    printf("a=%p,b=%p\n",&a,&b);    
}

int main(void)
{
    char a=0x11,b=0x22;

    func(a,b);

    return 0;
}

It is cleard in the above example: when calling func in main, there is no need to promote the arguments a and b, but the output shows &a = &b +4 not &a = &b+1. If no promotion occured, why 4 bytes between two CHAR argument?

HaoCheng
  • 135
  • 1
  • 4
  • Could you provide the source for your first paragraph? Where does it say that? – Matti Virkkunen May 31 '10 at 11:51
  • Expert C Programming----Peter Van Der Linden P207 Chapter 8 An additional place where implicit type conversion occurs is in argument passing.Under k&R C,since a function argument is an experssion, type promotion takes place there,too. In ANSI C, arguments are not promoted if a prototype is used; otherwise ,they are. Widened arguments are trimmed down to their declared size in the called function. – HaoCheng May 31 '10 at 12:08

1 Answers1

2

Because the compiler feels like doing it that way :-)

You can't infer that an argument has or hasn't been promoted just by looking at its address. There's no requirement that arguments be passed continguously on the stack (or even that they are passed on a stack at all, for that matter).

The compiler (and calling conventions for your platform) might specify that the stack is always kept 4-byte aligned, but that's an implementation-specific detail, not part of the C language standard.

David Gelhar
  • 27,873
  • 3
  • 67
  • 84
  • Which means it wasn't promoted at all in the above example? Could you please tell me why does a lib function such as 'ungetc' declared like this: int ungetc(int c,FILE *stream)?why not char ungetc(char c,FILE *stream)? And almost every func tend to use INT instead of CHAR in their prototype... – HaoCheng May 31 '10 at 12:20
  • The return value of 'ungetc' must be INT, not CHAR, because it needs to be able to return EOF (which is a value outside the range of CHAR). Similarly, the argument of 'ungetc' is INT because passing EOF is allowed: "If the value of the argument c character equals EOF, the operation will fail and the stream will remain unchanged." More generally, though, I suspect that the reason many standard library functions take INT is that they date back to K&R days, when promotion to INT was the rule. See http://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls – David Gelhar May 31 '10 at 15:09