printf("..\n") and scanf() in safari: input dialog is shown before output is printed

135 views
Skip to first unread message

Anton Smirnov

unread,
Oct 26, 2014, 6:49:59 AM10/26/14
to emscripte...@googlegroups.com
Few topics ago i've asked similar question and i was answered that printf needs '\n' or fflush() to force output. That works great in Google chrome but unfortunately does not work in Safari (which is default browser and widely used on mac). How can i force output or workaround it (i agree it can be Safari's bug/feature though)?

Full story:

#include <iostream>


using namespace std;


int main() {
   
char name[128];
    cout
<< "type your name:\n";
    cin
.getline(name, sizeof(name));
    cout
<< "hi, " << name << endl;


   
return 0;
}


In Safari input box is shown before "type your name" is printed:

I've try fflush(stdout) too, but unfortunately it does not help.

After text input done cout works as expected:

type your name: (input dialog shown and 'Anton' is typed)

hi, Anton




Alon Zakai

unread,
Oct 27, 2014, 3:27:45 PM10/27/14
to emscripte...@googlegroups.com
It might be that safari buffers the event to render the query, but immediately executes a prompt() call. I'm not sure if that would be a bug or not. You might need to just do it asynchronously, using emscripten_call_async etc.

- Alon


--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alecazam

unread,
Oct 31, 2014, 2:37:25 PM10/31/14
to emscripte...@googlegroups.com
Hey Anton,

You should know that fflush(stdout) was implemented in a patch to the code recently.  It was a no-op before.  You might just need to sync to that.   

/n should definitely not lead to an automatic fflush.  That's not the way printf functions, which is supposed to buffer output.  I never use cout.  cout is the worst api for atomicity and brevity of formatting.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.

Jukka Jylänki

unread,
Oct 31, 2014, 2:41:13 PM10/31/14
to emscripte...@googlegroups.com
Can you point to a reference on how the flushing should work then? Note that printing to a web console is line-based, so there is no way to flush without inserting a newline at the same time, which is why flushing is implemented at newline boundaries to preserve correct output. Flushing in the middle of a line would cause incorrect printing, and I don't think there is a performance benefit in flushing more seldomly either - that would just lead to more potential confusion.

To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

Anton Smirnov

unread,
Oct 31, 2014, 3:50:24 PM10/31/14
to emscripte...@googlegroups.com

Hi. Thanks for reply. I've tested print with '\n' and it works in chrome as expected (emscripten 1.25). But it does not work in safari (I can't see print before input dialog shown)

31 Окт 2014 г. 22:37 пользователь "Alecazam" <al...@figma.com> написал:

--
You received this message because you are subscribed to a topic in the Google Groups "emscripten-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/emscripten-discuss/5EN4FxJwYUU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to emscripten-disc...@googlegroups.com.

Alecazam

unread,
Nov 1, 2014, 2:01:49 PM11/1/14
to emscripte...@googlegroups.com
I'm not sure what you mean by flushing in the middle of the line.   fprintf(stderr)  is supposed to be unbuffered (flush after every call), and fprintf(stdout) should be buffered.  fflush(stdout) is the typical approach to turning stdout to the same behavior as stderr.   A typical printf line is the following.

printf("\nSomeText\n\n").   You definitely don't want three flushes from that.   I typically avoid direct use of printf in code, and wrap log statements around printf.  That way the logs can optionally flush (especially on warnings/errors), but buffer the rest of the outputs, and provide coloring to specific log types.  You'd be surprised at how log statements can bring down performance especially when you are shooting for 60 fps.

Anton Smirnov

unread,
Nov 1, 2014, 3:48:44 PM11/1/14
to emscripte...@googlegroups.com
Hi.

There was no intent to do flush in the middle of the line.

The expected behaviour is to print the line and then show input dialog:
printf();
scanf();

But in safari input dialog is shown before printf is actually finished (output visible).

fflush() was tried to fix/workaround this in safari.

Anton

--
You received this message because you are subscribed to a topic in the Google Groups "emscripten-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/emscripten-discuss/5EN4FxJwYUU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to emscripten-disc...@googlegroups.com.

Anton Smirnov

unread,
Nov 2, 2014, 2:06:42 AM11/2/14
to emscripte...@googlegroups.com
I've create issue:
https://github.com/kripken/emscripten/issues/2959

воскресенье, 26 октября 2014 г., 16:49:59 UTC+6 пользователь Anton Smirnov написал:

Anton Smirnov

unread,
Nov 6, 2014, 2:08:06 PM11/6/14
to emscripte...@googlegroups.com
I've tried to debug JavaScript step-by-step and it works as expected under debugging.
It makes me think it's timeout-related or concurrency-related issue.

Can anybody suggest something?


воскресенье, 26 октября 2014 г., 16:49:59 UTC+6 пользователь Anton Smirnov написал:
Few topics ago i've asked similar question and i was answered that printf needs '\n' or fflush() to force output. That works great in Google chrome but unfortunately does not work in Safari (which is default browser and widely used on mac). How can i force output or workaround it (i agree it can be Safari's bug/feature though)?

Anton Smirnov

unread,
Nov 6, 2014, 2:27:08 PM11/6/14
to emscripte...@googlegroups.com

This is main() code:

function _main() {
       
var $name = 0, $vararg_buffer = 0, $vararg_buffer1 = 0, $vararg_buffer3 = 0, label = 0, sp = 0;
        sp
= STACKTOP;
        STACKTOP
= STACKTOP + 96 | 0;
       
if ((STACKTOP | 0) >= (STACK_MAX | 0))
            abort
();
        $vararg_buffer3
= sp + 16 | 0;
        $vararg_buffer1
= sp + 8 | 0;
        $vararg_buffer
= sp;
        $name
= sp + 24 | 0;
       
(_printf((8 | 0), ($vararg_buffer | 0)) | 0);
        HEAP32
[$vararg_buffer1>>2] = $name;
       
(_scanf((32 | 0), ($vararg_buffer1 | 0)) | 0);
        HEAP32
[$vararg_buffer3>>2] = $name;
       
(_printf((40 | 0), ($vararg_buffer3 | 0)) | 0);
        STACKTOP
= sp;
       
return 0;
   
}

if i set breakpoint on _scanf i can see output is done, then i can continue execution and see input window.
If i remove breakpoint input dialog is shown without printf() output done.

Are there any delays or update() invocations() for output panel?
Is printf() async or synchronous executed?


воскресенье, 26 октября 2014 г., 16:49:59 UTC+6 пользователь Anton Smirnov написал:
Few topics ago i've asked similar question and i was answered that printf needs '\n' or fflush() to force output. That works great in Google chrome but unfortunately does not work in Safari (which is default browser and widely used on mac). How can i force output or workaround it (i agree it can be Safari's bug/feature though)?

Anton Smirnov

unread,
Nov 7, 2014, 1:20:29 AM11/7/14
to emscripte...@googlegroups.com
BTW, if i compile the source for node (./emcc .. -o input.js) and run 'node input.js' it does not stop at scanf()

MBA-Anton:tmp asmirnov$ node ./input.js
what
is your name ?
hi
,

 


 Is it something completely broken in my Emscrpten distrib (1.25.0)?

Reply all
Reply to author
Forward
0 new messages