5

Different outputs of sizeof() operator in C and C++.

In C:

int main() 
{
    printf("%zu\n", sizeof(1 == 1));
    return 0;
}

output:

4

In C++:

int main() 
{
    std::cout << sizeof(1 == 1) << std::endl;
    return 0;
}

output:

1

Questions:

  • Why are the outputs different?
  • Is sizeof independent of the OS or compiler?
  • Is it dependent on language?
Joshua
  • 40,822
  • 8
  • 72
  • 132
msc
  • 33,420
  • 29
  • 119
  • 214
  • 3
    `sizeof(bool)` and `sizeof(wchar_t)` are implementation-defined – P0W Aug 11 '17 at 11:49
  • 4
    Why is this question downvoted? – lilezek Aug 11 '17 at 11:51
  • 2
    `sizeof('a')` differs too. – Jonathan Leffler Aug 11 '17 at 11:53
  • 10
    @lilezek I did not downvote, but probably because the question is indeed not particularly useful. After all, C and C++ are different languages, they have subtle and not so subtle differences since the dawn of C++. Expecting arbitrary code to behave the same just shows neglect of that simple fact. – Baum mit Augen Aug 11 '17 at 12:01
  • @rsp it even more funny. If you take the same family of C compilers for different targets you will get the different results. For example `avr gcc` sizeof(1==0) will 2 and `ARM gcc` 4 :). Those deliberations are completely useless – 0___________ Aug 11 '17 at 12:20
  • 3
    @lilezek mmm..probably lack of research? [google result](https://www.google.com/search?q=result+of+comparison+operator+in+c+vs+c%2B%2B&oq=result+of+comparison+operator+in+c+vs+c%2B%2B&gs_l=psy-ab.3...1540.7416.0.7627.12.12.0.0.0.0.169.1172.6j5.11.0....0...1.1.64.psy-ab..1.9.888...33i22i29i30k1.Z3ZQp0h6H4o) and the [secnd hit](http://www.geeksforgeeks.org/results-of-comparison-operations-in-c-and-c/)?? – Sourav Ghosh Aug 11 '17 at 12:21
  • "Is sizeof not depend on the OS" --> No - for example an OS need not even exist. "... or Compiler?" --> Yes. It is a complier choice. The selection is primarily based on the processor. – chux - Reinstate Monica Aug 11 '17 at 12:23
  • 1
    C and C++ are different languages. It makes no sense to say "is this language dependent". Every feature of a language depends on that language. – M.M Aug 11 '17 at 12:52
  • I'm fairly certain that this has been asked many times before. – Lundin Aug 11 '17 at 13:07
  • 1
    "Why are the outputs different?" - because C and C++ are different languages, with different semantics. Most importantly, C is *not a subset* of C++ - there are legal C programs that are *not* legal C++ programs, and the behavior of programs that are legal in both languages are not guaranteed to be the same in both languages. – John Bode Aug 11 '17 at 15:58

3 Answers3

18

According to N1570 draft ():

6.5.9 Equality operators

The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence. Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int.

Therefore, the sizeof(1 == 1) will return equal value to sizeof(int) which is implementation defined and in your case it is 4.


According to N4296 draft ():

5.10 Equality operators

The == (equal to) and the != (not equal to) operators group left-to-right. The operands shall have arithmetic, enumeration, pointer, or pointer to member type, or type std::nullptr_t. The operators == and != both yield true or false, i.e., a result of type bool.

Therefore, the sizeof(1 == 1) will return equal value to sizeof(bool) which is implementation defined and in your case it is 1.

Akira
  • 4,385
  • 3
  • 24
  • 46
  • Both `sizeof( int )` and `sizeof( bool )` are *implementation defined*. They aren't fixed at `4` and `1`. See https://stackoverflow.com/questions/11438794/is-the-size-of-c-int-2-bytes-or-4-bytes and https://stackoverflow.com/questions/4897844/is-sizeofbool-defined – Andrew Henle Aug 12 '17 at 15:16
  • @AndrewHenle, thanks for your comment but I didn't mention that they have fixed value. Anyway I edited my answer to be more cleaner, emphasizing the fact that the results of `sizeof(int)` and `sizeof(bool)` are implementation defined. – Akira Aug 12 '17 at 16:51
15

In C result of == and != operators is int

According to N1570 draft - 6.5.9 Equality operators

4 means sizeof(int), but it depends on architecture.


In C++ result of == and != operators is bool

According to N4296 draft - 5.10 Equality operators

1 means sizeof(bool) the size cannot be smaller than one byte. But it would be legal to be larger than one byte.

kocica
  • 6,412
  • 2
  • 14
  • 35
  • 2
    C has a built-in type `_Bool`, but it is a late add-on and not used everywhere that it could (should?) be. – Jonathan Leffler Aug 11 '17 at 11:55
  • 3
    You say C doesn't have a built-in Boolean type, but it does. You should reword your answer. – Jonathan Leffler Aug 11 '17 at 11:59
  • 2
    "not used everywhere" --> All C99, C11 compliant compilers have `_Bool`. – chux - Reinstate Monica Aug 11 '17 at 12:16
  • 1
    @chux I'm reading 'not used everywhere' as 'not fully integrated into the language'. The result of `1==1` is `int` in C whereas a more comprehensive integration of `_Bool` would presumably revise that. Though it's difficult see any measurable benefit. – Persixty Aug 11 '17 at 13:30
  • @Persixty An interesting idea, yet a revision to `1==1` to something that is not `int` would break much code base. Such is the effect of adding improvements vs. legacy choices that carry momentum - for good or ill. – chux - Reinstate Monica Aug 11 '17 at 13:35
  • @chux I'm not advocating. But given "integer promotions" I can only think things like the original question and `_Generic` would differ. My problem is except for intellectual purity I don't see what it would add. – Persixty Aug 11 '17 at 14:15
7

Because the type of the result in C is int (and 4 bytes is a typical size) and in C++ it's bool (and 1 is the typical size for that).

These values are implementation dependent.

Here's a C11 program that demonstrates that using _Generic (typical output int 4):

#include <stdio.h>

void what_int(){
    printf("int %lu",sizeof(int));
}

void what_other(){
    printf("other ?");
}

#define what(x) _Generic((x), \
    int : what_int(),\
    default: what_other()\
)

int main(void) {

    what(1==1);

    return 0;
}

Here's a C++ program that demonstrates that using template specializaton (typical output bool 1):

#include <iostream>

template<typename T>
void what(T x){
   std::cout<<"other "<<sizeof(T);
}

template<>
void what(bool x){
   std::cout<<"bool "<<sizeof(bool);
}


int main(){
    what(1==1);
    return 0;
}

I can't readily think of any code that is both C and C++ that would have a different outcome. Please accept that as a challenge.

Persixty
  • 8,165
  • 2
  • 13
  • 35