0

I am storing a char in a long variable and trying to print it using printf.

long a = 'A';
printf("%c \n",a);

Considering default argument promotions the arguments get promoted to int but as long has higher rank than int it should not get promoted (or actually demoted) to int.

Now if it doesn't get promoted to int , in the printf statement isn't there a type mismatch as we are trying to print a long variable using %c. According to C standard this behavior should be undefined but the compiler is perfectly printing A as output without any error or warning. Why is it so ?

I am working on GCC codeblocks compiler.

klutt
  • 30,332
  • 17
  • 55
  • 95
LocalHost
  • 910
  • 3
  • 8
  • 24

2 Answers2

2

According to C standard this behavior should be undefined but the compiler is perfectly printing A as output without any error or warning. Why is it so ?

Undefined behavior means that the behavior is not defined. That means that you cannot really expect it to behave in a certain way. Some things are more likely than others, but UB basically means that anything can happen.

Plus, the reason you don't get warnings is that you have not activated warnings.

$ gcc -Wall main.c 
main.c: In function ‘main’:
main.c:6:14: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
    6 |     printf("%c \n",a);
      |             ~^     ~
      |              |     |
      |              int   long int
      |             %ld

I'd recommend compiling with -Wall -Wextra -pedantic -std=c11 -Werror

Note that the warning says format ‘%c’ expects argument of type ‘int’ so passing an int to %c is perfectly fine. If you pass a char it will get promoted to int.

Related:

Promotions: https://stackoverflow.com/a/46073296/6699433

Undefined behavior: https://stackoverflow.com/a/4105123/6699433

klutt
  • 30,332
  • 17
  • 55
  • 95
0

The ASCII value of 'A' is casted and stored as a long number, the printf function casts it back to char as for %c, and prints back the 'A'

Actually, 'A' is just a number which is defined in a standardized way, so should be no problems.

Correct me if I'm wrong.

  • `printf` is not required to do that cast – klutt May 16 '20 at 17:21
  • But anyway I think it implicitly casts.. C don't actually care about the data type unless for array and pointer stuff.. right? –  May 16 '20 at 17:35
  • 2
    For `%c`, `printf` attempts to get an `int` argument, and it then converts (or behaves as if it does) that to an `unsigned char` and prints that. But when a `long` is passed, `printf` is not expected to get that and cast it. Its behavior in OP’s attempt may be the same as if that were done, but there are various ways that result could come to be, and it is incorrect to say that `printf` converts a stored `long` to a character. Additionally, the C standard leaves the specification of character values quite loose. – Eric Postpischil May 16 '20 at 17:36
  • 1
    @EricPostpischil Your comments are often too good to be only comments. This as answer surely would help the OP at most as it shows what actually and apparently seems to be happen. – RobertS supports Monica Cellio May 16 '20 at 18:11