Can I make a custom header file named stdio.h and can use it in my program along with <stdio.h>?
C11 7.1.2p3:
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.
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.
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.
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.
Related
I'm currently toying around with the C library NanoVG library. The library depends on OpenGL fucntions and has 2 header files nanovg.h and nanovg_gl.h. The latter file contains part of the implementation. For convenience, I have placed these two header files in /usr/include/nanovg.
When I try to compile the following code to an object file, gcc does not complain:
// working.c
#include <GL/gl.h>
#include <nanovg/nanovg.h>
#define NANOVG_GL3_IMPLEMENTATION
#include <nanovg/nanovg_gl.h>
(Command: gcc -c working.c -o working.o)
Now, I copy the header files from /usr/include/nanovg/ to the working directory, and replace the code with:
// notworking.c
#include <GL/gl.h>
#include "nanovg.h"
#define NANOVG_GL3_IMPLEMENTATION
#include "nanovg_gl.h"
(Command: gcc -c notworking.c -o notworking.o)
Gcc now complains that some OpenGL functions are not declared:
... (many more similar complaints)
src/nanovg_gl.h: In function ‘glnvg__renderDelete’:
src/nanovg_gl.h:1540:3: warning: implicit declaration of function ‘glDeleteBuffers’; did you mean ‘glSelectBuffer’? [-Wimplicit-function-declaration]
1540 | glDeleteBuffers(1, &gl->fragBuf);
| ^~~~~~~~~~~~~~~
...
Why does one file compile smoothly but not the other?
A bit deeper:
Using the cpp tool, I found that the difference between the two pre-processed files is limited to # directives but I don't see any difference as far as the "C content" goes. Below is a snippet of the pre-processed working.c. If I add the # lines from the pre-processed notworking.c, then gcc no longer compiles the pre-processed working.c and complains about a missing declaration for glDeleteBuffers.
// ...
if (gl ==
// # 1533 "src/nanovg_gl.h" 3 4 // <- uncomment this line and glDeleteBuffers is considered missing by gcc
((void *)0)
// # 1533 "src/nanovg_gl.h" // <- idem
) return;
glnvg__deleteShader(&gl->shader);
if (gl->fragBuf != 0)
glDeleteBuffers(1, &gl->fragBuf); // <- the function that gcc complains about is here
// ...
Edit: Just to make sure that I did not do anything sneaky that might have caused the difference, I followed the following steps which hopefully should be reproducible on another computer:
GCC version: gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0
Copy the version of GL/gl.h can be found here to working directory and call it glfoo.h
Copy the headers of nanovg (as found in the repo) to /usr/include/nanovg/ and nanovg/ (relative to working directory).
Save the following as test.c in the working dir:
#include "glfoo.h"
#include <nanovg/nanovg.h>
#define NANOVG_GL3_IMPLEMENTATION
#include <nanovg/nanovg_gl.h>
Run gcc -c test.c -o test.o => compilation works
Replace <...> with ".." on lines 2 and 4 and run command => compilation fails.
Just tried these exact steps and I was able to reproduce it.
After investigating this a bit I found the solution. gcc does not apply the same warning level to system headers as it does for "normal" files (this is mainly because system headers are sometimes doing weird things which are not backed up by the C standard, but are "safe" for the platform they are coming with).
The gcc documentation states (emphasis mine):
-Wsystem-headers:
Print warning messages for constructs found in system header files. Warnings from system headers are normally suppressed, on
the assumption that they usually do not indicate real problems and
would only make the compiler output harder to read. Using this
command-line option tells GCC to emit warnings from system headers as
if they occurred in user code. However, note that using -Wall in
conjunction with this option does not warn about unknown pragmas in
system headers—for that, -Wunknown-pragmas must also be used.
When you include nanovg via <...>, it is treated as a system header.
So doing gcc -Wsystem-headers working.c actually will bring on the warning.
Note that your code is neither working in working.c nor notworking.c, as working.c just hides the warning messages. The proper way to access any GL function beyond what is defined in GL 1.1 is to use the GL extension mechanism, which means you have to query the GL function pointers at run-time. Full GL loader libs like GLEW and glad can do that for you automatically. Many of these loaders (including GLEW and GLAD) work by re-#define-ing every GL function name to an internal function pointer, so when you include the header which comes with the loader, every GL function called in your code (and nanovg's) will be re-routed to the loader-libraries function pointers, and your code can actually work (provided you properly initialize the loader at run-time before any of the GL functions is called).
simply
#include <file.h>
include file from the path listed default to the compiler, while
#include "file.h"
include file from the current folder (where you are compiling).
As in your case , switching from <> to "" makes come files missing which makes that compiler error coming.
There are two ways to include a file in C :
#include <headerpath/header.h>
or
#include "headerpath/header.h"
The first one will look for the file by using a directory known by the compiler, so we can include standard files without knowing where they are.
The second way will look for the file by using only the path between quotes. (if the search fails, the compiler tries the first way instead).
We have the possibility to add one or more directories into the directories's list that the compiler know (first way). For example with gcc we have the -I option.
So at the end, these two following codes are equivalent (path_to_header is a directory) :
1)
#include "path_to_header/header.h"
int main(void)
{
return (0);
} // Compiling with : gcc main.c
2)
#include <header.h>
int main(void)
{
return (0);
} // Compiling with : gcc main.c -I path_to_header
So my questions are :
With my own header files for example, should I use the 1) or the 2) ? Why ? Maybe it's just a personal choice ? Are there different situations to know ?
Thank's for reading :)
Edit :
I'm not looking for the difference between the two ways (I think I understood them as I explained, thanks to this post), I wanted to know if there are some special situations to know about, maybe for group work or using different compilers for the same program ... Maybe I do not know how to formulate my thoughts (or it's a silly question without real answer), I have to try to know :).
For headers of the standard libraries (which probably are precompiled) use:
#include <stdio.h>
For headers of your project use:
#include "project/header.h"
Use the option -I on the command line for additional libraries.
According to the C standard the only standard difference between them is that #include <...> includes a header while #include "..." includes a source file (and falls back to the <...> behavior if no source file is found). All other differences are implementation-defined.
The distinction is important because, for example, a standard header like stdlib.h might not actually be a file, and is instead injected by the compiler at compile time.
For your own code, since you won't have such header magic, and should know exactly which source files you want included from your own work and which you want the compiler to handle (system libraries and such) you should only use <...> for includes that are not part of your project's file structure.
If your own header files are in a defined path, like the same folder with your files that use your headers you must use this way "header.h".
You must use < header.h > when the header is a system header that is not with your sources where you are including it.
If I do this below:
#include <stdio.h>
int main()
{
printf ("%s\n",__FILE__);
return 0;
}
>gcc cfilename.c
>./a.out
>cfilename.c
>pwd
>/home/tek/cpp
> gcc -v
> gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
only file name is printed, I think it should print it with complete path, google search tells me people asking help to get only file name?
The ISO C standard (currently C11) has this to say about the content of the __FILE__ predefined macro:
__FILE__: The presumed name of the current source file (a character string literal).
And that's about it. There is no mandate on the format of the content so I suspect a implementation could probably get away with setting it to "some file I found in the /src tree" and still claim conformance.
So it's basically up to the implementation as to what it puts in there. You'll need to investigate specific implementations to see how they handle it. The gcc compiler, for example, uses the file exactly as you specified on the command line so, if you want the full path, it's the command line you'll have to change, something like:
gcc -o myexec $(pwd)/myexec.c
It's interesting to note that gcc seems to do the opposite for included files. When you use:
#include "myheader.h"
the __FILE__ macro is set to the full expansion of the header file.
If you have an implementation that doesn't set __FILE__ in the manner you need, there's nothing stopping you from creating your own with something like:
dodgycc -o myexec -DMY_FILE_NAME=$(pwd)/myexec.c myexec.c
(where the -D option of the dodgycc compiler defines a preprocessor token to be what you need).
Looking into learning C. As I understand it when I say #include <stdio.h> it grabs stdio.h from the default location...usually a directory inside your working directory called include. How do I actually get the file stdio.h? Do I need to download a bunch of .h files and move them from project to project inside the include directory? I did the following in a test.c file. I then ran make test and it outputted a binary. When I ran ./test I did not see hello print onto my screen. I thought I wasn't seeing output maybe because it doesn't find the stdio.h library. But then again if I remove the greater than or less than signs in stdio the compiler gives me an error. Any ideas?
I'm on a Mac running this from the command line. I am using: GNU Make 3.81. This program built for i386-apple-darwin10.0
#include <stdio.h>
main()
{
printf("hello");
}
Edit: I have updated my code to include a datatype for the main function and to return 0. I still get the same result...compiles without error and when I run the file ./test it doesn't print anything on screen.
#include <stdio.h>
int main()
{
printf("hello");
return 0;
}
Update:
If I add a \n inside of the printf it works! so this will work:
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
Your code should have preferably
printf("hello\n");
or
puts("hello");
If you want to know where does the standard header file <stdio.h> comes from, you could run your compiler with appropriate flags. If it is gcc, try compiling with
gcc -H -v -Wall hello.c -o hello
Pedantically, a standard header file is even not required to exist as a file; the standard permits an implementation which would process the #include <stdio.h> without accessing the file system (but e.g. by retrieving internal resources inside the compiler, or from a database...). Few compilers behave that way, most really access something in the file system.
If you didn't have the file, you'd get a compilation error.
My guess is the text was printed, but the console closed before you got the chance to see it.
Also, main returns an int, and you should return 0; to signal successful completion.
#include <header.h>, with angle brackets, searches in standard system locations, known to the compiler-- not in your project's subdirectories. In Unix systems (including your Mac, I believe), stdio.h is typically in /usr/include. If you use #include "header.h", you're searching subdirectories first and then the same places as with <header.h>.
But you don't need to find or copy the header to run your program. It is read at compilation time, so your ./test doesn't need it at all. Your program looks like it should have worked. Is it possible that you just typed "test", not "./test", and got the system command "test"? (Suggestion: Don't name your programs "test".)
Just going to leave this here : STILL! in 2018, December... Linux Mint 18.3
has no support for C development.
innocent / # cc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # gcc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # apt show libc6
(Abbreviated)::
Package: libc6
Version: 2.23-0ubuntu10
Priority: required
Section: libs
Source: glibc
Origin: Ubuntu
Installed-Size: 11.2 MB
Depends: libgcc1
Homepage: http://www.gnu.org/software/libc/libc.html
Description: GNU C Library: Shared libraries
Contains the standard libraries that are used by nearly all programs on
the system. This package includes shared versions of the standard C library
and the standard math library, as well as many others.
innocent / # apt-get install libc6-dev libc-dev
So, magic... and a minute later they are all installed on the
computer and then things work as they should.
Not all distros bundle up all the C support libs in each ISO.
Hunh.
hardlyinnocent / # gcc ThoseSorts.c
hardlyinnocent / # ./a.out
20
18
17
16
... ... ...
My understanding was always that by doing #include <header.h> it looks in the system include directories, and that #include "header.h" it looks in the local directory. But I was just looking at the python source code and it uses the "header.h" method to define headers in a sibling directory.
So in py3k/Python/ast.c it does #include "Python.h". But Python.h is in py3k/Include/Python.h
Is this something common that I've just never seen, not having worked on any real large C project? How do I tell, at least my IDE, to look in py3k/Include?
Update
I figured out how to tell my IDE to include them, it was just me being stupid and a spelling error. But I'm more interested in why "" works. Is that not the different between "" and <>?
Both #include <header> and #include "header" look in "implementation-defined places", i.e. it depends on the compiler you are using and its settings. For #include <h> it's usually some standard system include directories and whatever you configure the compiler to look in additionally.
The difference between the two versions is that if the search for #include "header" is not supported or fails, it will be reprocessed "as if it read #include <header>" (C99, §6.10.2).
You need to somehow tell your compiler what directories to search in -- for GCC this means using the -I flag. Look it up for your combination of IDE / compiler.