2

Following snippet of code is not working as I expected, the output of the following program is "S is Bigger" when compiled with GCC in an Ubuntu machine. Although the variable s is -1 and which is clearly smaller than sizeof(buffer) which is 20. But still it prints S is Bigger.

Only logical assumption I can make is that C is converting the variable "s" to unsigned integer and using in "If" condition. If My assumption is correct why C is doing that or if I am wrong why this snippet is giving this confusing output.

#include <stdio.h>

int main(void) {

    int s = -1;
    char buffer[20];

    if(s > sizeof(buffer)){
        printf("S is Bigger");
    }
    return 0;
}
ted
  • 3,911
  • 3
  • 26
  • 49

2 Answers2

4

From the answer to this question

It's safe provided the int is zero or positive. If it's negative, and size_t is of equal or higher rank than int, then the int will be converted to size_t and so its negative value will instead become a positive value.

sizeof() returns size_t

Community
  • 1
  • 1
  • 1
    When a new question has (pretty much) the same answer as an existing (answered) one, don't put (part of) that answer, as an answer to the new question: either mark the new question as a dup, or put a comment with a link to the existing answer. – CristiFati Jun 09 '16 at 22:28
  • @CristiFati this is OK IMO. It's not a duplicate question because the other question does not ask about comparing negative values, and the "duplicate" feature says that it is for duplicate questions. – M.M Jun 09 '16 at 22:30
  • 1
    @M.M Thank you for your comment. But I don't know if the sign of the operand(s) to compare makes any difference. It's about providing a solution consisting of (part of) something that was already provided as a solution (to a separate question). For example, a comment to the question pointing to that foreign question (with the right answer) would be OK (at least that's what I do - because I feel that answering with an existing answer wouldn't be quite ethically correct...it would mean taking some credit for someone else's work). – CristiFati Jun 09 '16 at 22:59
  • Providing a link to the original counts as crediting the original author – M.M Jun 09 '16 at 23:17
3

You are correct, the compiler converts s to the unsigned int data type size_t (which is the return value of sizeof operator). So the comparison become (on my system where size_t is 64 bit):

if (18446744073709551615 > 20)

which is clearly true ;)

This is part of the Implicit conversions defined by the standard. The relevant section is the "Usual arithmetic conversions" which is in 6.3.1.8 of the standard.

See also this post and this other post

Foundamental rules:

  • If both operands have the same type, no further conversion is needed.
  • If both operands are of the same integer type (signed or unsigned), the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
  • If the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type is converted to the type of the operand with unsigned integer type.
  • If the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type.
  • Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
Community
  • 1
  • 1
terence hill
  • 3,354
  • 18
  • 31