http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56549

             Bug #: 56549
           Summary: #pragma once ineffective with BOM in include file
    Classification: Unclassified
           Product: gcc
           Version: 4.6.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: pch
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: yurivk...@gmail.com


Created attachment 29594
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29594
Minimal example demonstrating the problem

When an include file starts with a UTF-8 byte order mark and is included in a
precompiled header, it is not protected against repeated inclusion.

Environment:
 * Ubuntu 12.04 amd64
 * GCC 4.6.3 from Ubuntu repo

To reproduce:

$ unzip pragma-once-bom.zip
$ make

The contents of the archive are listed below for convenience of discussion.

Foo.h:
===
<BOM>#pragma once

struct Foo {};
===

stable.h:
===
#include "Foo.h"
===

main.cpp:
===
#include "stable.h"

int main() { Foo foo; }
===

Makefile:
===
all: main.o

pragma-once.gch/c++: stable.h Foo.h
    @test -d pragma-once.gch || mkdir pragma-once.gch
    g++ -x c++-header -c stable.h -o pragma-once.gch/c++

main.o: main.cpp stable.h Foo.h pragma-once.gch/c++
    g++ -c -include pragma-once -o main.o main.cpp

clean:
    @rm -rf pragma-once.gch main.o
===

Expected behavior:

===
$ make
g++ -x c++-header -c stable.h -o pragma-once.gch/c++
g++ -c -include pragma-once -o main.o main.cpp
===

Observed behavior:

===
$ make
g++ -x c++-header -c stable.h -o pragma-once.gch/c++
g++ -c -include pragma-once -o main.o main.cpp
In file included from stable.h:1:0,
                 from main.cpp:1:
Foo.h:3:8: error: redefinition of ‘struct Foo’
Foo.h:3:8: error: previous definition of ‘struct Foo’
make: *** [main.o] Error 1
===

Workarounds/observations:

* If the header file does not contain a BOM, the problem does not occur.
* With include guards instead of #pragma once, the problem does not occur.
* In a real project, changing an #include <FooLib/Foo.h> to #include
<FooLib/./Foo.h> in the precompiled header stable.h, or changing an #include
<FooLib/Foo.h> to #include "Foo.h" in a different header included by stable.h,
also fixes the immediate problem.

Reply via email to