6

I'm not too familiar with programming in C (I've only done a few small projects in the language), however, my professor said something about it's behavior today that left me a bit confused.

What he said was that this code will sometimes not print anything at all (I copied down exactly what was on the board, I believe this is pseudocode for C since "print" is not in C):

    int a = ___________;
    int b = ___________;

    if (a < b)
   print (“<“);
    if (a > b)
   print (“>”);
    if (a==b)
   print(“=”);

Basically, there is something you could store in those int variables where none of these conditions would be met (the ____ isn't actual code obviously, it just represents that something is there). It doesn't necessarily need to be some int number that fills those blanks...it could be anything in the world (and there can be stuff that happened before this code).

What is it that could fill those blanks and wouldn't produce any result, and why?

p.s - it had something to do with an overflow, undefined behavior, out of bounds error, or something of the like

p.p.s - I have serious trouble believing this professor was mistaken. He is more knowledgable about programming than anyone I've ever come into contact with. I'm convinced there is some case where this is true.

Casey Patton
  • 4,021
  • 9
  • 41
  • 54
  • 6
    Your professor is wrong. – pmg May 13 '11 at 10:10
  • 2
    probably confusing a remark about floating point comparison there, C Man – sehe May 13 '11 at 10:13
  • I'm certain it was an int (further, I'm certain he wasn't referring to NaN). – Casey Patton May 13 '11 at 10:15
  • `print` is not defined by the Standard, `“>”` is not a proper string (the delimiters are *strange*), and if you invoke UB anything can happen. – pmg May 13 '11 at 10:15
  • your username is 'The C Man' but you not very familiar with the programming language :p – Andrew Jackman May 13 '11 at 10:16
  • I actually just changed my username to my real name...my name starts with a 'C' haha. Hasn't updated yet! – Casey Patton May 13 '11 at 10:18
  • pmg: This was pseudocode for C. Thanks for pointing that out, I just clarified this in my initial code. – Casey Patton May 13 '11 at 10:18
  • 4
    There are two options: 1. Your professor is wrong 2. You missunderstood what he said. – Andreas Brinck May 13 '11 at 10:19
  • Andreas: 1. Is an impossibility. No way this guy was wrong about C. 2. Highly, highly unlikely since I copied down everything word for word and listened to what he said. – Casey Patton May 13 '11 at 10:21
  • You did not copy an essential part: The placeholder behind the ints. – Gunther Piez May 13 '11 at 10:21
  • If there is case for `int` where this is true (which there isn't), there should be a case for `short` as well in which case you can loop over all possible values of `a` and `b` and see for yourself that something's always printed. – Andreas Brinck May 13 '11 at 10:26
  • 1
    I'll ask my professor about this as soon as I can (everyone not believing me has certainly heightened my interest in finding an answer). Sadly, I won't see him until Tuesday. If no one has solved this by then, I'll let you guys know on Tuesday what he said. – Casey Patton May 13 '11 at 10:41
  • short have different semantics, especially they are autopromoted to ints when used together. But with today's hardware he may loop over all ints in a few seconds. – Gunther Piez May 13 '11 at 10:41
  • @drhirsch Looping over all *pair* of ints will take considerable time, even on today's hardware. – Andreas Brinck May 13 '11 at 10:45
  • Hmm, that's true. You need a platform with 16 bit ints then :-) – Gunther Piez May 13 '11 at 10:55
  • Did you ever get an answer from your professor? – Andreas Brinck Aug 08 '11 at 15:12

8 Answers8

4

All that is necessary is for one of the int initialisations to generate a run-time exception. The program will then terminate prior to any of the comparison tests. E.g.

int b = *(int *)0;
Paul R
  • 208,748
  • 37
  • 389
  • 560
2

I guess it's the _ part that matters. If the underlined part contains code results UNDEFINED behavior, and the following code with comparisons get optimized by a "clever" compiler wrt the undefined behavior, the ultimate behavior of this piece of code is undefined. And not printing anything is a reasonable undefined behavior.

p.s. According to Wikipedia, division by zero results in undefined behavior, although most compilers define it an error. And IIRC signed integer overflow also causes undefined behavior, although again this usually cause runtime exception or even compilation error. So if a and b are declared as

int a = 1 / 0;
int b = INT_MAX + 1;

the situation your prof describes may occur. But remember, the behavior is undefined, so whatever the compiler chooses the program to behave might be considered conformant with the standard.

Chang Peng
  • 1,052
  • 8
  • 14
1

If you have an architecture with int numbers in one's complement, there exist two zeros: One with all bit set to 0 and one with all bit set to 1, aka positive and negative zero. Both zeros should compare equal, but a buggy compiler may not see that so ;-)

Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
0

For int this is not true, because they have no "special" values.

murrekatt
  • 5,961
  • 5
  • 39
  • 63
0

p.s - it might have had something to do with an overflow?

I think this is what your professor meant:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char** argv)
{
    uint8_t a = 100;
    uint8_t b = 200;

    a = a + b; /* a = 300 in your head. This overflows, so 300-256=44 */

    if ( a > b )
    {
        printf("%u > %u", a, b);
    }
    else if ( a < b )
    {
        printf("%u < %u", a, b);
    }
    else
    {
        printf("%u == %u", a, b);
    }

    return 0;
}

Specifically, I am using a fixed width 8-bit unsigned integer, which can hold at maximum 8 bits (surprise) which represents 256 as the largest possible integer. You can overflow this field by adding to it an amount that can't be represented in this size, in which case what you're left with is a wrap-around effect.

There is no actual ambiguity in the if comparison logic, since that's actually part of the processor (if translates to one of the comparison / jump instruction combinations). The issue is that you might have programmed it reasonably expecting it to work, not realising that number representations on a computer all have fixed representations. I can't see anything I could put into those registers that would possibly escape all of "less, greater or equal".

Note I've used the C99-introduced fixed size integers for clarity and small number sizes so we can do it in our head.

  • 3
    He said the professor claimed that this code would sometimes not print anything at all, this code prints "44 < 200" – Andreas Brinck May 13 '11 at 10:29
  • Yes, it will. But even with signed types, you're just altering a register. I cannot think of any way you could possibly fail, even if you compared a pointer to an integer since a pointer in a register is just a number. I can only think he must have been trying to make the point about integer overflow. –  May 13 '11 at 10:33
0
a = 0, b = 5 / a : divide by zero
EdChum
  • 376,765
  • 198
  • 813
  • 562
Amir
  • 32
  • 3
0

Given that "there can be stuff that happened before this code"...

#include <stdio.h>
#include <math.h>

int main(void)
{

#define int float

    int a = nanf(NULL);
    int b = nanf(NULL);

    if (a < b)
       printf("<\n");
    if (a > b)
       printf(">\n");
    if (a == b)
       printf("==\n");

    return 0;
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
0

Maybe the defintion of print is:

void
print(const char*) {    
}
Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114