0

I wanted _Generic to work for the char data type:

#include <stdio.h>


#define test(x) _Generic((x), \
    char: 0, \
    int: 1, \
    double: 3, \
    default: 4 \
)


int main()
{
    printf("%c\n", test('c')); // Result was ☺ character so I switched to %d
    printf("%d\n", test('c')); // 1, which I would have received if 'c' was an int but 'c' is a char


    return 0;
}

By the way I am aware that chars are technically ints. I just want to know if there is any way to fix this so it prints 0 instead.

Here is a link if you need information about _Generic: http://www.robertgamble.net/2012/01/c11-generic-selections.html

  • 2
    *"I am aware that chars are technically ints."* So what are you **really** trying to do? – dbush Dec 15 '22 at 13:15
  • 3
    [`'c'` is an int](https://stackoverflow.com/questions/433895/why-are-c-character-literals-ints-instead-of-chars) – user253751 Dec 15 '22 at 13:15
  • @dbush I want to receive only a char, not an int. As you saw in the printfs the results were different. Is there any way _Generic can distinguish between an int or a char or are chars and ints not different in any way apart from size? –  Dec 15 '22 at 13:17
  • 2
    @user20598969 A character constant has type `int`. What you have is no different than `test(99)` (assuming ASCII). So why do you think you need to know whether a character constant was passed? – dbush Dec 15 '22 at 13:20
  • @dbush So chars are virtually the same as ints? I guess I wanted to experiment with _Generic to do a form of generic programming. Does this mean that I can store a char inside of an int? –  Dec 15 '22 at 13:23
  • 3
    @user20598969 Character constants have type `int`. Variables of type `char` are `char`. Given `char c;`, then `test(c)` would evaluate to 0. – dbush Dec 15 '22 at 13:26

1 Answers1

-2

It is because char constants have type int. If you cast it to char it will work as expected

#define test(x) _Generic((x), \
    char: 0, \
    int: 1, \
    double: 3, \
    default: 4 \
)

int main()
{
    printf("%d\n", test((char)'c')); 
    printf("%d\n", test((char)99)); 
    return 0;
}

https://godbolt.org/z/Mea1v8jv6

0___________
  • 60,014
  • 4
  • 34
  • 74
  • 2
    Why re-open the question? The underlying problem is clearly the fact that char literals are `int`, which was already answered by the two duplicates I had linked (and probably many more). Did you just reopen it to post this answer? Come on... – Marco Bonelli Dec 15 '22 at 14:55
  • 2
    And additionally, of course casting to `char` solves the problem... but why would you cast to `char` if the whole purpose of `test()` is to *determine the type* of the passed value? That doesn't make much sense, it means you already know the type. – Marco Bonelli Dec 15 '22 at 15:00
  • 2
    @MarcoBonelli The first duplicate you picked wasn't great (and ironically, answered by yours sincerely) since it was mostly about escape sequences. The second one answered by Antti Haapala is a good duplicate however - I've closed the question again. – Lundin Dec 15 '22 at 15:04