-9

Passing characters to a scanf with a %d specifier resulted in random numbers all around 32,760. I am using the GCC available with Ubuntu 16.04. My guess is, obviously, that this is unspecified behavior. But any idea as to what's going on under the hood?

Here is the rather obvious code for aforementioned objective:

#include <stdio.h>

void main() {
  int n;
  scanf("%d", &n);
  printf("\n%d", n);
}

The input supplied was repeatedly the letter 'a' followed by pressing an Enter to terminate terminal talk. The results for the first three runs were : 32765, 32764, 32767.

In response to some helpful suggestions, I've thus figured that scanf doesn't initialize n. But it does something. Consider this code:

#include<stdio.h>   
int main() {
    int i;
    for(i=0; i<10; i++)
    {
        int n;
        printf("%d", n);
    }
}

This gives me a row of ten zeroes for the output. I'm flummoxed. The question probably isn't interesting, I get it. But I just can't not stop wondering why. I still can't rule out the effect of scanf because of this.

  • 1
    Hello and Welcome to StackOverflow! Currently, you are showing us no code, so it is nearly impossible to tell where problem comes from. Please read [ask] and add a [mcve] to your question. – Ben Steffan Jun 03 '17 at 16:42
  • Are you really using '%d'? you must pass a string specifier, i.e., you should use "%d" instead of '%d'. – douglasjfm Jun 03 '17 at 16:43
  • We can't help you unless you share your code. – Govind Parmar Jun 03 '17 at 16:43
  • @DouglasMedeiros Please read the title. The mismatch is intended. – YetAnotherEntity Jun 03 '17 at 16:45
  • I would like to know why my question has received down voting. It's a genuine question, I can not find duplicates and I have added code. Constructive criticism is welcome. – YetAnotherEntity Jun 03 '17 at 17:05
  • @YetAnotherEntity Do you have read the manual of [`scanf()`](https://linux.die.net/man/3/scanf). Duplicate ? ok [here](https://stackoverflow.com/questions/40551037/scanf-not-working-on-invalid-input), [here](https://stackoverflow.com/questions/34560317/scanfd-a-with-a-while-grammer-bypass-the-scanf). – Stargateur Jun 03 '17 at 17:13
  • 2
    You said "this is unspecified behavior" and that is what it is. So asking why an uninitialised and unwritten variable is giving the results you get, is pointless. It is undefined. My first three runs produced `1687249147` and `1692353513` and `2073092923`. So what? – Weather Vane Jun 03 '17 at 17:13
  • @Stargateur Thank you for the edits. Your two links, albeit interesting, does not flatter to an answer. – YetAnotherEntity Jun 03 '17 at 17:19
  • @WeatherVane I like how agreeable you are with my hypothesis. However, it's the diagnosis for the symptom that I'm looking for. Chiefly, what's with the numbers being so close to the max cap of an integer? – YetAnotherEntity Jun 03 '17 at 17:20
  • For all we know, it might be because you are using an obsolete definition of `main`. And perhaps, because you are printing a `newline` before, and not after, the result, you are getting the value from the *previous* run and the current value is still in a buffer ;) – Weather Vane Jun 03 '17 at 17:28
  • Since you don't test the result of `scanf()`, you don't notice that it has failed and not set the uninitialized variable `n` to a known value. You get what you get because you're invoking undefined behaviour. Check that `scanf()` succeeds (returns 1) before trying to use the value it is supposed to have read. Or initialize `n` before invoking `scanf()`, but you'd do better to test the result of `scanf()` — you need to do that every other time you ever use it. – Jonathan Leffler Jun 03 '17 at 21:48
  • @YetAnotherEntity I can't speak for others, but I suspect the downvoting was because of some combination of the facts that at the beginning you posted no actual code, and you were argumentative towards the people who conscientiously tried to answer the question you seemed to be asking, and because the (very different) question you were actually asking was not the question you seemed to be asking, and because the question you were actually asking (a bit more on this below) isn't very interesting. – Steve Summit Jun 03 '17 at 21:54
  • So it seems what you're actually wondering is, "Why does the uninitialized variable `n` start out containing a value very close to 2^15?", or perhaps, "Why does it start out containing a slightly different value every time?". Uninitialized variables are rarely *completely* random, and the values often end up being close to 0, or -1, or 2^N. There are all sorts of possible reasons why. But the answer (whatever it is) has to do with whatever was leftover on the stack to receive. The answer has *nothing* to do with `scanf`, because here `scanf` isn't modifying `n` at all. – Steve Summit Jun 03 '17 at 22:02
  • If you really want to explore the possible reasons why an uninitialized variable might start out containing values very close to 2^15, I encourage to write test programs focusing on that, or post a new question focusing on that, and leave `scanf` completely out of it. – Steve Summit Jun 03 '17 at 22:09
  • @WeatherVane Could you please specify which compiler, and processor you used? – YetAnotherEntity Jun 04 '17 at 06:49
  • @JonathanLeffler You are absolutely right, that scanf doesn't initialize n. But please note my new edit. – YetAnotherEntity Jun 04 '17 at 06:50
  • Your new code doesn't prove anything. `n` is still uninitialized, and any value, including `0`, is permissible. Using my default compilation options on your code `gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition xx37.c -o xx37` produces errors: `xx37.c:2:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]` `xx37.c: In function ‘main’:` `xx37.c:2:5: error: old-style function definition [-Werror=old-style-definition]` `xx37.c:7:9: error: ‘n’ is used uninitialized in this function [-Werror=uninitialized]`. – Jonathan Leffler Jun 04 '17 at 07:14
  • When I use the basic compilation: `gcc -o xx37 xx37.c` and run it: `./xx37`, I got the output `236261430236261430236261430236261430236261430236261430236261430236261430236261430236261430`. That doesn't prove anything except that I'm a stubborn cuss and `n` was uninitialized to `236261430` on my machine (a Mac running macOS Sierra 10.12.5 and using GCC 7.1.0). A different run repeated `118226998` 10 times. – Jonathan Leffler Jun 04 '17 at 07:16
  • IMO this sort of question becomes interesting when: suppose a function is misbehaving, yet it is bug-free. Then I discover a bug in an unrelated part of the program, and suspect that its side-effect manifests in the problemmatic function, which works correctly after the bug is fixed. It is sometimes possible to observe the outcome of undefined behaviour to satisfy myself that the fault really was caused by the unrelated bug, and not by something else yet to be discovered. For example the bug was in a section that prints the date and the number 2017 turns up in the wrong place. – Weather Vane Jun 04 '17 at 07:19
  • @WeatherVane Wow. I wonder I'd love to hear of an experience so unlikely as that. I can't remember but there was this computer fantasy anecdote where someone hard coded some 'drums' that put something into an infinite loop. I wish I could recollect. But interesting note. – YetAnotherEntity Jun 04 '17 at 15:53
  • It is not at all unlikely and is no fantasy. If a fault was corrected by fixing an unrelated bug (this is not rare), I need a level of confidence that the fault was *consistent* with what the bug was doing, and not the outcome of some other bug that has shifted its effect slightly after making changes to the code. – Weather Vane Jun 04 '17 at 16:04
  • @JonathanLeffler I rest my case, this has been a hassled morbid journey. My apologies to all involved. :) – YetAnotherEntity Jun 04 '17 at 16:19

1 Answers1

0

I changed your program to

#include <stdio.h>

int main() {
  int n;
  printf("%d\n", n);
  scanf("%d", &n);
  printf("%d\n", n);
}

When I run it with the input "a", it prints

32767
32767

So whatever is causing n to start out with the bit pattern for 32767, it is not anything that scanf is doing.

At one level this is interesting, perhaps even fascinating: despite the fact I'm using a very different system (clang-600.0.57 under MacOS 10.9.5), I got a remarkably similar result. But no matter how intriguing this is, I'm not going to waste time trying to figure out why, because it'd be hard, and it wouldn't teach me anything useful about writing proper programs. It's just some random, meaningless coincidence.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103