LWN.net Logo

Simple

Simple

Posted Nov 2, 2011 21:31 UTC (Wed) by khim (subscriber, #9252)
In reply to: I think it's pretty clear, actually... by quotemstr
Parent article: libabc: a demonstration library for kernel developers

When include files are copied around they sometimes treated as the same from "#pragma once" POV (if copying process keeps the timestamps) and sometimes as different (if you put them in GIT and pull back).

Thus "#pragma once" is great way to create unreproducible build failures. With explicit include guard you sometimes trigger the GCC optimization (GCC does not reread file with include guard it it can understand that it's the same file) and sometimes it fails and GCC actually loads and parses file again - but it only affects compilation speed, never correctness.


(Log in to post comments)

Simple

Posted Nov 2, 2011 21:36 UTC (Wed) by quotemstr (subscriber, #45331) [Link]

> When include files are copied around they sometimes treated as the same from "#pragma once" POV (if copying process keeps the timestamps) and sometimes as different (if you put them in GIT and pull back).

I've never seen this behavior. Any decent implementation of #pragma once should not flag two files with different contents as identical. Very old compilers were sometimes confused by various links of link, but this issue hasn't cropped up in a very long time.

Please provide a pointer to a bug report or at a set of setps to demonstrate the behavior you describe.

Hmm... Very simple test...

Posted Nov 3, 2011 13:20 UTC (Thu) by khim (subscriber, #9252) [Link]

$ mkdir test1
$ mkdir test2
$ echo '#pragma once' > test1/test.h
$ echo 'abc' >> test1/test.h
$ cp -ai test1/test.h test2/test.h
$ echo '#include "test1/test.h"' > test.c
$ echo '#include "test2/test.h"' >> test.c
$ gcc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
# 1 "test1/test.h" 1

abc
# 2 "test.c" 2
$ touch test2/test.h
$ gcc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
# 1 "test1/test.h" 1

abc
# 2 "test.c" 2
# 1 "test2/test.h" 1

abc
# 2 "test.c" 2
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 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.

This is just a preprocessor test, but compiler does the same thing.

Note that usually we do want this behavior (these files are identical - they come from the same source, after all) - and usually it works, but sometimes when you do complex manipulations (git in my case, but of course it's not the only possibility) everything blows up.

There is always a well-known solution to every human problem--neat, plausible, and wrong.

Well, "#pragma once" is such a solution - don't use it.

Simple

Posted Nov 3, 2011 0:56 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link]

We have a project with 20 identically named .h files (don't ask). #pragma once works just fine.

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds