Can I make a custom header file named stdio.h
and can use it in my program along with <stdio.h>
?

- 131,814
- 10
- 121
- 189

- 419
- 1
- 4
- 13
-
4Why would you want to? Are you seeking some extra problem in your life? – Eugene Sh. Aug 17 '17 at 17:33
-
just asking if it is restricted or we can do that – Nakul Sharma Aug 17 '17 at 17:34
-
The algorithms of searching the headers in `<>` and in `""` are different, so yes, you can get away with this. https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html – Eugene Sh. Aug 17 '17 at 17:35
-
1Umm.. you could just err.. try it? – Martin James Aug 17 '17 at 17:44
-
1@EugeneSh: One possible reason to do it would be to declare some functions that are not present in the regular `
` header on the current platform, but which are available on other platforms (`vasprintf()`, or `getline()`, or …), and you will then provide the missing implementations. Such a mechanism is tricky at best — error prone at worst. You would probably do better with `#include "project/stdio.h"` which provides the extra functionality. Or `#include "aux_stdio.h"` or some other name. – Jonathan Leffler Aug 17 '17 at 17:45 -
1@MartinJames: The trouble with 'just try it' is that it might work on one type of machine and not on any others. The question doesn't state whether that would be a problem; it doesn't give any motivation for why the OP would want to play with fire and wonder whether their fingers will get burned. – Jonathan Leffler Aug 17 '17 at 17:51
4 Answers
If a file with the same name as one of the above < and > delimited sequences, not provided as part of the implementation, is placed in any of the standard places that are searched for included source files, the behavior is undefined.
The standard places then refers to 6.10.2p2:
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.
So the only guarantee given here is that if your stdio.h
is not in an implementation-defined place for a searching a header, then the behaviour wouldn't be undefined. You can then include it with
#include "stdio.h"
However if you really intended that the file would be included with
#include <stdio.h>
then for the compiler to find it you need to place it in any of the standard places, and all bets are off.
However, in a freestanding - i.e. not hosted - execution environment. stdio.h
might not be a standard header name so it might as well be perfectly OK there. Not that there is anything portable about the freestanding execution environment.
Thus, unless you specify more specifically what you're up to, we can only refer to the C standard and shrug. Having a source file named stdio.h
isn't strictly conforming but it very much might be conforming, so YMMV.

- 129,958
- 22
- 279
- 321
-
1Or, in other words, you can do it if you are foolish enough, but it is at your own risk and not portable or reliable. – Jonathan Leffler Aug 17 '17 at 17:40
I've created a file named as stdio.h and main.c afterwards added this content to main.c to test out if it works properly.
#include "stdio.h"
#include <stdio.h>
int main()
{
testArea(); // this will use "stdio.h"
int test = 2;
printf("%d", test); // this will use <stdio.h>
return 0;
}
Program output:
1002 (100 from "stdio.h" and 2 from <stdio.h>)
Content of my stdio.h:
#include <stdio.h>
void testArea()
{
int abc = 100;
printf("%d", abc);
}
Surprise surprise, it does! Now, you should know that using "" means searching header file via file path. Meanwhile <> basically looks at the includes folder of the compiler.
So that, you can do that.
PS: If you're going to downvote, make an explanation so that I can learn what's wrong too. It just works fine for me.
Edit: Now, you can see that program knows what to call and what to do.
Bonus: If you try to add a same name function that exists in the file compiler will give you an error.
#include <stdio.h>
void testArea()
{
int abc = 100;
printf("%d", abc);
}
void printf()
{
}
Will return stdio.h:9:7: error: conflicting types for ‘printf’
as an example. You just should avoid using existing functions, but it's not restricted to same name header files. You just can't do it with any filename since the names are going to conflict.
Again, the usage of this is fine. There should be no problems at all.
Edit 2: I'm using Linux Mint 18.2
.
Here is my gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
And, here is how I compile my code:
duman@duman-pc ~/Desktop/Nuclear Test Zone $ gcc main.c -o test
duman@duman-pc ~/Desktop/Nuclear Test Zone $ ./test
Nothing fancy, and I don't really know what can cause undefined behaviour since my compiler won't allow usage of same name functions.
Edit 3: Just to see if anything related to name usage throws a warning I compiled the same code with ALL of these flags: https://stackoverflow.com/a/34971392/7735711 and there were none about the names.
That's the best I can do. Hopefully it helps you.

- 910
- 8
- 25
-
1Not my DV, but… What did you put in `"stdio.h"`? How do you know your file was read? How do you know that the standard file was read? Your program doesn't demonstrate that any crucial information was read from either header. That makes your proof of concept very weak (if not pointless). – Jonathan Leffler Aug 17 '17 at 17:44
-
1Hmmm; the header should declare and not define the function. You should also be compiling with options such that you get warnings (preferably errors) for missing declarations. However, you've now done the minimum necessary to show it works on your (as yet unidentified) platform, with your (as yet unrevealed) compiler options. What you've shown doesn't contravene the standard, which says the behaviour is undefined. One version of 'undefined behaviour' is "appears to work sensibly even though it is not guaranteed to do so". – Jonathan Leffler Aug 17 '17 at 17:54
-
@JonathanLeffler alright, I'm a bit new around. I'll learn it slowly but surely. Thanks for guiding me. I'm also posting what I'm using to do it. Second edit is here. – Tuğberk Kaan Duman Aug 17 '17 at 18:01
-
Thanks for adding the information. You could try adding the `-I.` option to your compilation and seeing whether things break. It is often sufficient to say "compiling with GCC 5.4.0 on Linux Mint 18.2". (I routinely identify my test environment as "a Mac running macOS Sierra 10.12.6 and GCC 7.2.0", for example — both the OS version and the GCC version change periodically, and GCC 7.2.0 was released earlier this week.) – Jonathan Leffler Aug 17 '17 at 18:15
If you specify where in your file directory your custom "stdio.h" comes from (i.e. doing
#include "C:/ProgrammingC/stdio.h"
is probably fine, but
#include "stdio.h" //This only selects the standard include
//if there's no other stdio.h in the build directory
is risky, and
#include <stdio.h>
is definitely not what you want.

- 195
- 11
-
And having backslashes in `#include` statements has undefined behaviour too ;) – Antti Haapala -- Слава Україні Aug 17 '17 at 17:45
-
That's not undefined behavior. It has always worked fine under dos/windows, and never under linux un*x.. – Michaël Roy Aug 17 '17 at 17:50
-
@MichaëlRoy yes it is: *"The characters ', \, ", //, or /\* occur in the sequence between the < and > delimiters, or the characters ', \, //, or /\* occur in the sequence between the " delimiters, in a header name preprocessing token"* – Antti Haapala -- Слава Україні Aug 17 '17 at 17:52
-
@AnttiHaapala Really? I didn't know that. It works for me, but that could be true. Also I did mistype, I use forward slashes. – Stephen P Aug 17 '17 at 17:54
-
@MichaëlRoy backslashes do not work in GCC, so it might be that MingW complains for example. – Antti Haapala -- Слава Україні Aug 17 '17 at 17:56
-
-
@AnttiHaapala: Where did you get your quote about characters from? The C standard defines that, in a `#include` directive, what appears between `<` and `>` is an _h-char-sequence_ and what appears between `"` and `"` is a _q-char-sequence_, and §6.4.7 (and §A.1.8) Header names says 'h-char: any member of the source character set except the new-line character and `>`' and 'q-char: any member of the source character set except the new-line character and `"`'. That doesn't match what you quote. I agree you play with fire with some of those, but the standard isn't the source. – Jonathan Leffler Aug 17 '17 at 18:07
-
@JonathanLeffler n1570 6.4.7p3. It is part of syntax but semantics: UB. – Antti Haapala -- Слава Україні Aug 17 '17 at 18:10
-
@AnttiHaapala Well, I'm not going to change files that have compiled under DOS and Windows for 20+ years on account of that. – Michaël Roy Aug 17 '17 at 18:11
-
@MichaëlRoy your code is conforming, it is just not strictly-conforming. We had this as a problem when compiling some stuff with MingW instead of MSVC / other Windows compilers. – Antti Haapala -- Слава Україні Aug 17 '17 at 18:12
-
@AnttiHaapala: OK — that's fine; I'd done my searching on 'h-char-sequence' and although I'd got to §6.4.7 (after finding §A.1.8), I'd not scanned ¶3 — I had to scroll down a little to show it. Compilers normally define what happens with at least some of these characters in the names. POSIX requires compilers to accept names such as `
`, for example. – Jonathan Leffler Aug 17 '17 at 18:19
As noted by Antti Haapala, it is explicitly described as undefined behavior to name a file stdio.h
and put it in any of the directories where the compiler looks for include files.
Yet, by default, the compiler does not search for standard headers in the directory of the source file, but a command line argument of -I.
can easily change this behavior.
Without this option and assuming you do not put your source files in the compiler's system directories, you could use the name stdio.h
for an include file and include that with #include "stdio.h"
without interfering with the standard header referred to in #include <stdio.h>
(which might not even be a file at all).
You could go one step further into confusion-land by naming the source file itself stdio.h
...
I you truly want to confuse the reader, name the source file a.out
and compile with gcc -o stdio.h -x c a.out
.

- 131,814
- 10
- 121
- 189