-4

I am aware that the code I show below is incorrect, but I wonder why the stdio.h is blamed with:

appeared exeption in <stdio.h> script:

  __retval = __mingw_vfprintf( stdout, __format, __local_argv );

segmentation fault int stdout.

Code for beginners, actually:

#include <stdio.h>

int main()
{
printf(12345);
return 0;
}

I know that is might be incorrect, but i think, error should appeared in my file, but not in the script <stdio.h> file.

The main question for me, is why if i would call printf(Hello World), it won't show me the <stdio.h> error, but as for 12345 it shows? I started C language today, no practice, sorry)

Fus Ro
  • 17
  • 2
  • 1
    Please turn all compiler warnings to the max. You’re calling `printf` incorrectly so it will crash wherever it will, if it will. With a debugger you can see the whole call stack and determine where it originated. – Sami Kuhmonen Jun 29 '22 at 10:31
  • 2
    Page 1, chapter 1 of any beginner-level C book typically demonstrates how to print an integer using printf. As for the reason why you get a bug, you are using some gcc non-standard extension allowing implicit conversions from integers to pointers, so the lib tries to access address 12345. Which you don't have access to. – Lundin Jun 29 '22 at 10:32
  • `printf()` is a function present in the `stdio.h` file (standard input output). When you call the function, and there is some error in the function, then ofc the error will appear in `stdio.h`. – The Coding Fox Jun 29 '22 at 10:35
  • @SolvedGames I think you might be the only one who read the question to the end and carefully enough. I bow my head and reopen-vote to let you make an answer. – Yunnosch Jun 29 '22 at 10:37
  • @SolvedGames No, run-time errors will not obviously appear in _any_ header file since they typically don't (shouldn't) contain any executable code at all. – Lundin Jun 29 '22 at 10:40
  • I edited the question to make the point more obvious. Solved games spotted it, while I missed it. I do not know what the answer is. Maybe more details are needed. But the close vote reason (which I participated in) as "typo, not repdrocuable" I cannot uphold. I ask for answers or for more analysis via clarification questions. Fus Ro, I hope this is in line with your question. Otherwise please undo my edit and please take my apology for confusing everybody even more. – Yunnosch Jun 29 '22 at 10:44
  • Oh ffs... fine, I'll vote to re-open but the answer is pretty uninteresting... – Lundin Jun 29 '22 at 10:47
  • @Yunnosch It's ok bro :) – The Coding Fox Jun 29 '22 at 10:55
  • "if i would call printf(Hello World), it won't show me the error" But you do get other errors then, don't you? They probably override. Also, I suspect that you are not clearly enough distinguishing compile time, link time and runtime. I propose to give more details on when you get which message/error. – Yunnosch Jun 29 '22 at 11:00
  • When running under mingw64/gdb in debug mode, it's a run-time error spat out by gdb: "0x00007ff7f4471817 in printf (__format=0x3039 ) at c:/program files/mingw-w64/x86_64-w64-mingw32/include/stdio.h:372" And it points at some wrapper function in stdio.h indeed. If you just run it in release mode you just get access violation, poof. – Lundin Jun 29 '22 at 11:04
  • @Yunnosch yes, but as for other libraries, i've already tried with c++ , and there aren't any script exeptions, but the error is same, and GNU GCC is same. – Fus Ro Jun 29 '22 at 11:05
  • 1
    My point is, if you purposely blow up a bomb in your own house, there's no interesting mystery "why did the toilet fly into the neighbours' garden and not into the street". Who cares. Focus on not blowing things up instead of analysing the aftermath of your explosions, where it is unlikely you'll find anything of interest. – Lundin Jun 29 '22 at 11:09
  • C++ overloaded stream operators are more powerful/flexible and are intricatly programmed to give a more "tolerant" impression. Mixing C and C++ is risky. Please provide all your observations (paying attention to "when" details). printf(12345) and printf(Hello World) I predict to get very different errors. I think there is an interesting question here. You just need to make it visible and more answerable.... – Yunnosch Jun 29 '22 at 11:09
  • @Yunnosch This code is neither valid C nor valid C++ however... so might as well try to run it in Pascal and see what happens there as well, right? Very interesting. – Lundin Jun 29 '22 at 11:10
  • If I find my car as smoking wreck with lots of extinguisher foam, along with a bill by the firedepartment in my mailbox. Then I might try to find out how to read the bill in order to learn a) not to (stupidly) transport my still blazing BBQ b) not to park it were the local gangs do their well-known annual car-BBQ So learning how to interpret messages to the point where I know to blame myself or some infrastructure/environment is pretty interesting. Yes. Doing some experiments (this part does not translate well to car-BBQs....) might not be unwise. @Lundin – Yunnosch Jun 29 '22 at 11:16
  • @Lundin Maybe it's hard to understand, I'm trying to make "Work on mistakes", i'm not fond of asking every stupid question, if it appears. That's why i need to know, "why did the toilet fly into the neighbours", because after that, i will know "how to detonate a bomb so that the toilet does not fly to the neighbors" – Fus Ro Jun 29 '22 at 11:23
  • @FusRo No you won't, since this is the realm of undefined behavior and when you do things outside the scope of the language there is no guarantees of any logical or deterministic outcome. Another compiler or standard lib might give a different outcome, or simply refuse to generate a binary at all. – Lundin Jun 29 '22 at 11:34
  • `printf(Hello World),` would be a syntax error. Do you mean `printf("Hello World");`? – KamilCuk Jun 29 '22 at 11:37

2 Answers2

0

The problem is in your code of course:

printf(12345);

The first parameter of the printf function has to be a format string. In your case you pass the integer converted to pointer (it is very unlikely this pointer to reference the valid memory). printf function tries to derefence it and you get a segfault.

To print 12345 you need to:

printf("%d", 12345);

The main question for me, is why if i would call printf(Hello World), it won't show me the <stdio.h> error

printf("hello world"); is correct as the fist parameter is a valid C string.

0___________
  • 60,014
  • 4
  • 34
  • 74
0

First of all, this code is not valid C. A correctly configured compiler (https://software.codidact.com/posts/282565) may simply refuse to generate a program, because of the "Pointer from integer/integer from pointer without a cast" issues.

Some compilers like gcc/mingw might allow implicit conversions from integer to pointers when you run them in lax, non-standard mode. 12345 is then treaded as the address value of the char* format string that printf expects.

As for why the code crashes in some stdio.h header, it first of all depends on how you execute the code - you'll have to run it in a debugger (mingw/gdb) to know where it crashed, or otherwise the OS will just say access violation (Windows) or seg fault (*nix).

When running this in mingw64/gdb, I can reproduce the crash as:

#2 0x00007ff7f4471817 in printf (__format=0x3039 <error: Cannot access memory at address 0x3039>) at c:/program files/mingw-w64/x86_64-w64-mingw32/include/stdio.h:372

It points at the printf function inside stdio.h which as it turns out is just a thin wrapper around an internal library function __mingw_vfprintf:

__retval = __mingw_vfprintf( stdout, __format, __local_argv );

This is as deep as my mingw64 lets me go in C code, likely the definition of this function sits in a static linked lib and there's no C code for it that I have access to.

As for the machine code, it crashes on this specific assembler instruction:

0x7ff7f44758e2  movzx  eax,BYTE PTR [rax]

This appears to happen during the stacking required by the __cdecl calling convention for the printf call. rax contains the magic number 0x3039 aka 12345 when this happens. Exactly what caused the MMU to freak out, I don't know, but we do know that 0x3039 is not a valid address (and misaligned at that). Some x86 assembler guru can perhaps explain why exactly this happened in this particular ISA... but this is already way too deep for the average C programmer to care.

Lundin
  • 195,001
  • 40
  • 254
  • 396