-2

I'm trying to do this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAX_SIZE 50
int main()
{
    char *s = malloc(sizeof(char)*MAX_SIZE);
    do{
      int r = read(STDIN_FILENO, s, MAX_SIZE);
      if(r==-1) printf("error ");

      else{
        write(STDERR_FILENO, s, MAX_SIZE);
      }

      while(getchar()!='\n');
    } while(strcmp(s,"end\n")!=0);

    free(s);
    return 0;
}

My question is: is fflush(stdin) in this case an undefined behavior? As I searched on internet, I readed that in a case fflush(stdin) is a defined behavior: By the standard C pass an input stream to fflush is an undefined behavior ... STDIN is an input stream (buffered) I think the undefined behavior is when the standard C doesn't specify which behavior must have a specific function in specific cases.

So it is an undefined behavior by following the standard C right?

So is in this case an undefined behavior?

Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
John S.
  • 27
  • 6
  • 1
    Not a good idea to mix stdio library and using raw file descriptors. – Ed Heal Sep 10 '15 at 09:57
  • 2
    This question is very unclear. You've shown some code which doesn't use `fflush` and is full of irrelevant distractions, the `malloc` and `free` are useless (just use `char s[50]`), `MAX_SIZE` is useless, `sizeof(char)` is useless etc. Also the "question" is the same thing repeated 3 or 4 times with slightly different phrasing and poor punctuation, then you ask the same question twice more. Couldn't the whole thing be simply "is `fflush(stdin)` undefined behaviour?" and get rid of all the rest?! – Jonathan Wakely Sep 10 '15 at 10:02
  • Why a bad idea? @Ed Heal – John S. Sep 10 '15 at 10:03
  • Because stdio uses a buffer, raw pointers does not. Things get confusing. – Ed Heal Sep 10 '15 at 10:35
  • Ok ... Now I understood ... But why 'sizeof(char)' are useless? No-sense ... They let you read easily the source and is portability – John S. Sep 10 '15 at 11:01
  • @JohnS. - `sizeof(char)` is defined to always be 1, even on odd systems where `char` is larger than 8 bits. – Bo Persson Sep 10 '15 at 11:06
  • Then it's useless? And why? – John S. Sep 10 '15 at 11:11
  • 1
    Because `sizeof(char)` is always 1 on all systems everywhere, you can just write 1. It's simpler. Your example could have just used `char s[MAX_SIZE];` and not needed malloc, free or sizeof(char) at all. – Jonathan Wakely Sep 10 '15 at 11:13
  • Sizeof(char) is defined as one. - code using if seems cluttered – Ed Heal Sep 10 '15 at 11:17
  • Yes, this is true, but linux disposes function to get a descriptor file from a file pointer. It's good to use them. – John S. Sep 10 '15 at 11:47
  • (functions like fileno() ) – John S. Sep 10 '15 at 11:54

1 Answers1

2

The description of fflush in the C standard seems clear:

If stream points to an output stream or an update stream in which the most recent operation was not input, [...]; otherwise, the behavior is undefined.

Passing an input stream to fflush is undefined behaviour.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 1
    [SingleUnix](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html) adds behavior for seekable input streams. I'm not so sure if this is actually useful and implemented anywhere, though. – dhke Sep 10 '15 at 10:09
  • Thank you very much! Now I understood. Thanks. – John S. Sep 10 '15 at 10:19
  • 1
    @dhke, that's a good point, POSIX (which is implemented very widely!) makes it defined as an extension to the base C standard. But it only has an effect for streams capable of seeking, which stdin typically isn't. – Jonathan Wakely Sep 10 '15 at 10:32
  • 1
    That *implemented anywhere* was meant to specifically refer to this particular feature. Because e.g. on Linux and FreeBSD `fflush()` the man page documents behavior as to simply signal `EBADF` for input streams. Solaris documents POSIX behavior, though. – dhke Sep 10 '15 at 10:54