Calypso icon indicating copy to clipboard operation
Calypso copied to clipboard

Header included multiple times with pragma once

Open neikeq opened this issue 4 years ago • 1 comments

I have two headers:

// foo_a.h
#pragma once

#include "foo_b.h"
// foo_b.h
#pragma once

static int FOO = 10;

Notice how foo_a.h includes foo_b.h. If I try to include both headers from D in the following order:

// test.d
pragma(cppmap, "foo_a.h");
pragma(cppmap, "foo_b.h");

import (C++) *;

I get this redefinition error because foo_b.h is being included twice, which shouldn't happen with pragma once:

binary    /root/Calypso/build/bin/ldc2
version   1.18.0-git-1821f18-dirty (DMD v2.088.1, LLVM 9.0.1)
config    /root/Calypso/build/bin/ldc2.conf (x86_64-pc-linux-gnu)
calypso   driver args: clang -c -x c++-header .calypso_cache/calypso_cache.h 
predefs   LDC all D_Version2 assert D_ModuleInfo D_Exceptions D_TypeInfo X86_64 D_InlineAsm_X86_64 D_HardFloat LittleEndian D_LP64 D_PIC linux Posix CRuntime_Glibc CppRuntime_Gcc LDC_LLVM_900 CppStdLib_libstdcxx
parse     test
importall test
import    object        (/root/Calypso/runtime/druntime/src/object.d)
import    core.internal.array.appending (/root/Calypso/runtime/druntime/src/core/internal/array/appending.d)
import    core.internal.array.comparison        (/root/Calypso/runtime/druntime/src/core/internal/array/comparison.d)
import    core.internal.array.equality  (/root/Calypso/runtime/druntime/src/core/internal/array/equality.d)
import    core.internal.array.casting   (/root/Calypso/runtime/druntime/src/core/internal/array/casting.d)
import    core.internal.array.concatenation     (/root/Calypso/runtime/druntime/src/core/internal/array/concatenation.d)
import    core.internal.array.construction      (/root/Calypso/runtime/druntime/src/core/internal/array/construction.d)
import    core.internal.array.capacity  (/root/Calypso/runtime/druntime/src/core/internal/array/capacity.d)
import    core.internal.hash    (/root/Calypso/runtime/druntime/src/core/internal/hash.d)
import    core.internal.traits  (/root/Calypso/runtime/druntime/src/core/internal/traits.d)
import    core.internal.convert (/root/Calypso/runtime/druntime/src/core/internal/convert.d)
In file included from .calypso_cache/calypso_cache.h:1:
In file included from /root/calypso-issue-pragma-once/foo_a.h:4:
/root/calypso-issue-pragma-once/foo_b.h:4:12: error: redefinition of 'FOO'
static int FOO = 10;
           ^
/root/calypso-issue-pragma-once/foo_a.h:4:10: note: '/root/calypso-issue-pragma-once/foo_b.h' included multiple times, additional include site here
#include "foo_b.h"
         ^
/root/calypso-issue-pragma-once/foo_a.h:4:10: note: '/root/calypso-issue-pragma-once/foo_b.h' included multiple times, additional include site here
Error: Invalid C/C++ header(s)

It doesn't happen if test.d includes foo_b.h before foo_a.h. It doesn't happen if test.d includes foo_b.h twice either (while not including foo_a.h).

Everything works well when using header guards in foo_b.h instead of pragma once.

issue-pragma-once.zip

neikeq avatar Apr 27 '20 00:04 neikeq

As far as I can recall, #pragma once is actually not standard C++

That being said, it's really widely supported so I would also like to see it implemented.

devbat8712 avatar Jun 03 '20 01:06 devbat8712