#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2

    Difference between getc and fgetc


    is, according to the man page, that getc
    may be implemented as a macro which evaluates stream more than once
    what does this mean?
    1. what is an evaluation of a stream?
    is it to read what characters are present in the stream?
    (e.g. text file contains "120 30 W")
    2. what does it mean to "implement as a macro"?
    how do you treat a function as a constant macro?
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Here is an example, showing how (not) to write a function-like macro, how it evaluates the parameter more than once, and how it is broken if you pass a parameter with side effects.
    Code:
    #include <stdio.h>
    
    // This is a macro which evaluates it's parameter more than once.
    // It is BROKEN if the parameter has side effects.
    #define SQR(x)  ((x)*(x))
    
    int sqr ( int x ) {
      return x * x;
    }
    
    int main (  ) {
      int x = 1, y = 1, i;
      for ( i = 0 ; i < 10 ; i++ ) {
        printf("%d %d\n", SQR(x++), sqr(y++) );
      }
      return 0;
    }
    
    
    
    $ gcc -W -Wall -Wextra bar.c
    bar.c: In function ‘main’:
    bar.c:14:23: warning: operation on ‘x’ may be undefined [-Wsequence-point]
    $ ./a.out
    1 1
    9 4
    25 9
    49 16
    81 25
    121 36
    169 49
    225 64
    289 81
    361 100
    GCC can even warn you when you're doing something suspicious with side-effects.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2
    Thanks.

    Code:
    #define SQR(x)  ((x)*(x))
    So this is a function as a macro; I didn't know you could do that.

    I did understand what a "function macro" is, and how a parameter would be evaluated more than once, but how would you use getc to evaluate the parameter more than once?
    I can see the SQR function evaluates the parameter twice. However, I have trouble picturing a situation where getc evaluates stream (its paramter) twice or more.
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    You mean like this (bad) example, of trying to read a single character from 10 different files at once.
    Code:
    FILE *arrayOfFiles[10];
    
    while ( i < 10 ) {
      c[j++] = getc( arrayOfFiles[i++] );
    }
    If getc() is a function, there is no problem.
    If getc() is a macro which evaluates the stream expression once, there is no problem.
    If getc() is a macro which .... - you know that you're in deep doodoo now.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper

IMN logo majestic logo threadwatch logo seochat tools logo