user13357160
user13357160

Reputation:

Why does C language allow users to create Macros whose name are the same as a pre-existing library function?

# include <stdio.h> 
# define scanf  "%s Hello World" 
int main (void) 
{ 
   printf(scanf, scanf); 
   getchar(); 
   return 0; 
}

In the above code snippet, before the code is executed, the macro expansion phase takes place. In this, each occurrence of 'scanf' is replaced by "%s Hello World".

Hence printf(scanf,scanf) will become printf(“%s Hello World” , “%s Hello World”).

The final output will be :

%s Hello World Hello World

Now, no problems were encountered in this program because we did not use the scanf function here.

However, if we use the scanf function for some purpose

# include <stdio.h> 
# define scanf  "%s Hello World" 
int main(void) 
{ 
   int x;
   printf(scanf, scanf); 
   scanf("%d",&x);
   getchar(); 
   return 0; 

}

We encounter an error :

main.c: In function ‘main’:
main.c:2:17: error: called object is not a function or function pointer
 # define scanf  "%s Hello World" 
                 ^
main.c:7:4: note: in expansion of macro ‘scanf’
    scanf("%d",&x);
    ^~~~~

Why does then C allow us to name macros after library functions like Scanf in the first place ?

Upvotes: 2

Views: 490

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 223264

C 2018 7.1.3 1 says:

… Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

scanf is an identifier with file scope listed in a following subclause (7.21), and you include its header, , so it is reserved for use as a macro name.

7.1.3 2 says:

… If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

Combined, these rules say that, if you define scanf as a macro name and include <stdio.h>, the C standard does not impose any requirements on what happens—it is not specified to be an error in your program, nor is the compiler required to reject your program as incorrect. The compiler is also not required not to reject your program.

There is an alternative which avoids this problem: You can omit #include <stdio.h> and instead declare printf (and any other functions from <stdio.h> that you use) yourself. The C standard explicits allows this, and then you can freely define a macro for scanf.

This is typical of much of the C standard: It does not prevent you from doing things that can cause problems. In particular, it does not require the compiler warn you about it. There are at least three reasons (good or bad) the C standard is designed this way:

  • It allows flexibility and extensions. C was designed to be a portable language, not in the sense that a program works in the same way everywhere but in the sense that C can be implemented for a variety of computing platforms with relative ease. The C standard allows flexibility so the language can be adjusted to a platform, and it allows implementations to provide extensions to the language beyond what the standard specifies.
  • It reduces the work load on compilers. By not imposing many requirements on compilers, it makes it easier to write them. (Then, whether to implement extra checks on programs becomes a matter of quality rather than of adherence to the C standard. This policy has worked well. Even without requirements from the standadr, today’s widely available compilers are much higher quality than those of decades ago.)
  • It allowed some code written before the C standard was published to continue working with the standard. Before there were rules about using library functions as macro names, some programs may have been written that did so (which programmers might do because they wanted to somewhat alter the library function, at least in appearance). Requiring compilers to reject those programs would require work to be done to get those programs working with the new language standard.

Upvotes: 5

Related Questions