-2

Who know the root cause of print order error? How to resolve it? I compiled the following code to assembly:

{
    int a, b;

    sprint("input number\n");
    scan  (a);
    iprint(a);
}

This generated the following assembly code:

    IO:
    .string "%lld\n"
    .text
    .globl main
main:
    pushq %rbp
    movq %rsp, %rbp
    subq $32, %rsp
    .data
L1: .string "input number"
    .text
    leaq L1(%rip), %rcx
    movq $0, %rax
    subq $32, %rsp
    callq printf             <-------printf
    addq $32, %rsp
    movq %rbp, %rax
    leaq -8(%rax), %rax
    movq %rax, %rdx
    leaq IO(%rip), %rcx
    subq $32, %rsp
    callq scanf             <---------scanf
    addq $32, %rsp
    movq %rbp, %rax
    leaq -8(%rax), %rax
    movq (%rax), %rax
    pushq %rax
    popq  %rdx
    leaq IO(%rip), %rcx
    subq $32, %rsp
    callq printf            <--------printf
    addq $32, %rsp
    leaveq
    retq

I installed Embarcadero-dev-cpp on my windows 7 and used gcc tmp.s to get a execute file a.exe, and then ran a.exe

$ ./a.exe
987                 <-----my input, should be the second display
input number        <-------should be print firstly
987                 <-------the last.
jason@jason-PC ~/samplecygwin
$

The cation order of printf, scanf is wrong.

My high language code is translate to assembly code. Should I insert flush(stdout) after printf in my compiler? Thank you. it's a common problem, but only meet seldom, refer to the following please.

scanf before printf - C

printf before scanf doesn't show printf string before input

Scanf executed before printf in Eclipse

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • What are the definitions of `sprint`, `scan` and `iprint`? – Michael Jan 14 '22 at 11:18
  • I don't think you wrote a compiler. You probably wrote a program and compiled it ;-). By the way, it is always helpful for us to see an entire program, ideally boiled down to a minimal example. – Peter - Reinstate Monica Jan 14 '22 at 11:59
  • 1
    @Peter-ReinstateMonica: In [call scanf system subroutine to input a integer number but error in the execute](https://stackoverflow.com/q/70690919), the querent says their *professor* wrote a compiler, https://www.ed.tus.ac.jp/j-mune/ccp/. This insanely bloated asm is much more easily explained by a toy compiler than being hand-written, e.g. `movq %rbp, %rax` / `leaq -8(%rax), %rax` / `movq %rax, %rdx` instead of `lea -8(%rbp), %rdx` – Peter Cordes Jan 14 '22 at 15:19

1 Answers1

1

This is typically because of output buffering: The printf call is happening as expected (as you verified by looking at the generated assembler) but nothing shows on the screen: It all went to some buffer and is waiting there patiently until some amount of output data has accumulated that's worthwhile to suspend the program and call an operating system routine for. A typical buffer size would be 4096 bytes. You can verify this theory by writing 4096 (or maybe 4097) characters to stdout, or if that doesn't work, the next powers of 2 until something shows.

Side note: On a normal terminal scanf would automatically cause a flush of stdout exactly to avoid this situation. Maybe Embarcadero (which is a GUI oriented IDE) uses input and output for a console program that is not identifiable as a terminal so that this doesn't work. Out of curiosity you could try to find out where the executable is, open a normal Windows Console and execute your program directly per command line. I'd not be surprised if it worked as expected.

What can you do with your program to make it work properly wit Embarcadero? You can fflush() stdout each time you want to see output on the screen, or call setbuf() once and have everything show from then on.

But it is debatable whether you should clutter up your program at all because of a misbehaving development environment. If you can run it successfully as-is through a regular console I'd rather do that.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • 2
    `fprintf` to `stderr` would be another way to work around a buggy environment, although it's more normal to print interactive prompts on stdout, I think, for programs that prompt and read stdin instead of taking command-line args. – Peter Cordes Jan 14 '22 at 15:08
  • @PeterCordes Correct on both fronts, I'd say ;-). Interacting on stderr as a workaround seems much worse than flushing/setbuffing stdout. – Peter - Reinstate Monica Jan 14 '22 at 18:00