Skip to content

Instantly share code, notes, and snippets.

@kikairoya
Last active May 7, 2025 12:18
Show Gist options
  • Save kikairoya/7fe9136c9ee2de5fe9ca19a26193f620 to your computer and use it in GitHub Desktop.
Save kikairoya/7fe9136c9ee2de5fe9ca19a26193f620 to your computer and use it in GitHub Desktop.
$ TARGET=x86_64-pc-cygwin ./run_test.sh
x86_64-pc-cygwin-gcc (GCC) 15.0.1 20250406 (experimental)
Copyright (C) 2025 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.
no annotation, dll, reference directly
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=0x5bad42060 sv(via outer)=0x5bad42060 sv(direct)=0x5bad42060
dllexport/dllimport, dll, reference directly
DECLSPEC_OUTER='__attribute__((dllimport))' DECLSPEC_INNER='__attribute__((dllimport))' EXTERN='extern'
sv=0x5bad42060 sv(via outer)=0x5bad42060 sv(direct)=0x5bad42060
dllexport/dllimport to outer only, dll, reference directly (should causes link error)
/usr/lib/gcc/x86_64-pc-cygwin/15/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccSt4G85.o:test.cc:(.rdata$.refptr._ZN5outerIiE5inner2svE[.refptr._ZN5outerIiE5inner2svE]+0x0): undefined reference to `outer<int>::inner::sv'
collect2: エラー: ld はステータス 1 で終了しました
./run_test.sh: 行 45: ./test.exe: No such file or directory
dllexport/dllimport to outer only, dll, reference via outer
DECLSPEC_OUTER='__attribute__((dllimport))' DECLSPEC_INNER='' EXTERN='extern'
sv=0x5bad42060 sv(via outer)=0x5bad42060
visibility-default, dll, reference directly
DECLSPEC_OUTER='__attribute__((visibility("default")))' DECLSPEC_INNER='__attribute__((visibility("default")))' EXTERN='extern'
sv=0x5bad42060 sv(via outer)=0x5bad42060 sv(direct)=0x5bad42060
no annotation, static lib, reference directly
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=0x100402060 sv(via outer)=0x100402060 sv(direct)=0x100402060
x86_64-w64-mingw32-gcc (GCC) 14.2.0
Copyright (C) 2024 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.
no annotation, dll, reference directly
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=000000037ad43070 sv(via outer)=000000037ad43070 sv(direct)=000000037ad43070
dllexport/dllimport, dll, reference directly
DECLSPEC_OUTER='__attribute__((dllimport))' DECLSPEC_INNER='__attribute__((dllimport))' EXTERN='extern'
sv=000000037ad43070 sv(via outer)=000000037ad43070 sv(direct)=000000037ad43070
dllexport/dllimport to outer only, dll, reference directly (should causes link error)
/usr/lib/gcc/x86_64-w64-mingw32/14/../../../../x86_64-w64-mingw32/bin/ld: /tmp/cc9H8O9D.o:test.cc:(.rdata$.refptr._ZN5outerIiE5inner2svE[.refptr._ZN5outerIiE5inner2svE]+0x0): undefined reference to `outer<int>::inner::sv'
collect2: エラー: ld はステータス 1 で終了しました
./run_test.sh: 行 45: ./test.exe: No such file or directory
dllexport/dllimport to outer only, dll, reference via outer
DECLSPEC_OUTER='__attribute__((dllimport))' DECLSPEC_INNER='' EXTERN='extern'
sv=000000037ad43070 sv(via outer)=000000037ad43070
visibility-default, dll, reference directly
DECLSPEC_OUTER='__attribute__((visibility("default")))' DECLSPEC_INNER='__attribute__((visibility("default")))' EXTERN='extern'
sv=000000037ad43070 sv(via outer)=000000037ad43070 sv(direct)=000000037ad43070
no annotation, static lib, reference directly
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=00000001400080c0 sv(via outer)=00000001400080c0 sv(direct)=00000001400080c0
$ TARGET=x86_64-w64-mingw32 CC=clang ./run_test.sh
clang version 19.1.7
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: /usr/bin
no annotation, dll, reference directly
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=000000037AD48170 sv(via outer)=000000037AD48170 sv(direct)=00000001400081E0
dllexport/dllimport, dll, reference directly
test.cc:12:22: error: definition of dllimport static field not allowed
12 | int outer<T>::inner::sv = 0;
| ^
test.cc:4:12: note: attribute is here
4 | struct DECLSPEC_INNER inner {
| ^
<command line>:2:35: note: expanded from macro 'DECLSPEC_INNER'
2 | #define DECLSPEC_INNER __declspec(dllimport)
| ^
1 error generated.
./run_test.sh: 行 38: ./test.exe: そのようなファイルやディレクトリはありません
dllexport/dllimport to outer only, dll, reference directly (should causes link error)
DECLSPEC_OUTER='__attribute__((dllimport))' DECLSPEC_INNER='' EXTERN='extern'
sv=000000037AD48170 sv(via outer)=000000037AD48170 sv(direct)=00000001400081E0
dllexport/dllimport to outer only, dll, reference via outer
DECLSPEC_OUTER='__attribute__((dllimport))' DECLSPEC_INNER='' EXTERN='extern'
sv=000000037AD48170 sv(via outer)=000000037AD48170
visibility-default, dll, reference directly
DECLSPEC_OUTER='__attribute__((visibility("default")))' DECLSPEC_INNER='__attribute__((visibility("default")))' EXTERN='extern'
sv=000000037AD48170 sv(via outer)=000000037AD48170 sv(direct)=00000001400081E0
no annotation, static lib, reference directly
clang: warning: -Wl,--disable-dynamicbase: 'linker' input unused [-Wunused-command-line-argument]
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=00000001400081E0 sv(via outer)=00000001400081E0 sv(direct)=00000001400081E0
$ PATH=$HOME/llvm-project/build-stage2/bin:$PATH TARGET=x86_64-w64-mingw32 CC=clang ./run_test.sh
clang version 21.0.0git (llvm-project cygwinmod)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: /home/kikai/llvm-project/build-stage2/bin
no annotation, dll, reference directly
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=000000037ad47110 sv(via outer)=000000037ad47110 sv(direct)=000000037ad47110
dllexport/dllimport, dll, reference directly
test.cc:12:22: error: definition of dllimport static field not allowed
12 | int outer<T>::inner::sv = 0;
| ^
test.cc:4:12: note: attribute is here
4 | struct DECLSPEC_INNER inner {
| ^
<command line>:2:35: note: expanded from macro 'DECLSPEC_INNER'
2 | #define DECLSPEC_INNER __declspec(dllimport)
| ^
1 error generated.
./run_test.sh: 行 38: ./test.exe: No such file or directory
dllexport/dllimport to outer only, dll, reference directly (should causes link error)
/usr/bin/x86_64-w64-mingw32-ld: /tmp/test-7786b9.o:test.cc:(.rdata$.refptr._ZN5outerIiE5inner2svE[.refptr._ZN5outerIiE5inner2svE]+0x0): undefined reference to `outer<int>::inner::sv'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
./run_test.sh: 行 45: ./test.exe: No such file or directory
dllexport/dllimport to outer only, dll, reference via outer
DECLSPEC_OUTER='__attribute__((dllimport))' DECLSPEC_INNER='' EXTERN='extern'
sv=000000037ad47110 sv(via outer)=000000037ad47110
visibility-default, dll, reference directly
DECLSPEC_OUTER='__attribute__((visibility("default")))' DECLSPEC_INNER='__attribute__((visibility("default")))' EXTERN='extern'
sv=000000037ad47110 sv(via outer)=000000037ad47110 sv(direct)=000000037ad47110
no annotation, static lib, reference directly
clang: warning: -Wl,--disable-dynamicbase: 'linker' input unused [-Wunused-command-line-argument]
DECLSPEC_OUTER='' DECLSPEC_INNER='' EXTERN='extern'
sv=000000014000cb80 sv(via outer)=000000014000cb80 sv(direct)=000000014000cb80
#!/bin/bash
if [[ -z "$TARGET" ]]; then
TARGET=x86_64-pc-cygwin
fi
if [[ $CC = *clang ]]; then
cc() {
clang -target "$@" -Wl,--disable-dynamicbase
}
else
cc() {
t=$1
shift
$t-gcc "$@" -Wl,--disable-dynamicbase
}
fi
if ! type x86_64-pc-cygwin-ar > /dev/null 2>&1; then
x86_64-pc-cygwin-ar() {
ar "$@"
}
fi
cc $TARGET --version
echo "no annotation, dll, reference directly"
rm -f test_dll.dll test.exe
cc $TARGET -DDECLSPEC_OUTER="" -DDECLSPEC_INNER="" -DEXTERN="" -DDIRECT test.cc -shared -o test_dll.dll
cc $TARGET -DDECLSPEC_OUTER="" -DDECLSPEC_INNER="" -DEXTERN="extern" -DDIRECT -DEXE test.cc test_dll.dll -o test.exe
./test.exe
echo ""
echo "dllexport/dllimport, dll, reference directly"
rm -f test_dll.dll test.exe
cc $TARGET -DDECLSPEC_OUTER="__declspec(dllexport)" -DDECLSPEC_INNER="__declspec(dllexport)" -DEXTERN="" -DDIRECT test.cc -shared -o test_dll.dll
cc $TARGET -DDECLSPEC_OUTER="__declspec(dllimport)" -DDECLSPEC_INNER="__declspec(dllimport)" -DEXTERN="extern" -DDIRECT -DEXE test.cc test_dll.dll -o test.exe
./test.exe
echo ""
echo "dllexport/dllimport to outer only, dll, reference directly (should causes link error)"
rm -f test_dll.dll test.exe
cc $TARGET -DDECLSPEC_OUTER="__declspec(dllexport)" -DDECLSPEC_INNER="" -DEXTERN="" -DDIRECT test.cc -shared -o test_dll.dll
cc $TARGET -DDECLSPEC_OUTER="__declspec(dllimport)" -DDECLSPEC_INNER="" -DEXTERN="extern" -DDIRECT -DEXE test.cc test_dll.dll -o test.exe
./test.exe
echo ""
echo "dllexport/dllimport to outer only, dll, reference via outer"
rm -f test_dll.dll test.exe
cc $TARGET -DDECLSPEC_OUTER="__declspec(dllexport)" -DDECLSPEC_INNER="" -DEXTERN="" test.cc -shared -o test_dll.dll
cc $TARGET -DDECLSPEC_OUTER="__declspec(dllimport)" -DDECLSPEC_INNER="" -DEXTERN="extern" -DEXE test.cc test_dll.dll -o test.exe
./test.exe
echo ""
echo "visibility-default, dll, reference directly"
rm -f test_dll.dll test.exe
cc $TARGET -DDECLSPEC_OUTER='__attribute__((visibility("default")))' -DDECLSPEC_INNER='__attribute__((visibility("default")))' -DEXTERN="" -DDIRECT test.cc -shared -o test_dll.dll
cc $TARGET -DDECLSPEC_OUTER='__attribute__((visibility("default")))' -DDECLSPEC_INNER='__attribute__((visibility("default")))' -DEXTERN="extern" -DDIRECT -DEXE test.cc test_dll.dll -o test.exe
./test.exe
echo ""
echo "no annotation, static lib, reference directly"
rm -f test_lib.a test_lib.o test.exe
cc $TARGET -DDECLSPEC_OUTER="" -DDECLSPEC_INNER="" -DEXTERN="" -DDIRECT test.cc -c -o test_lib.o
$TARGET-ar rc test_lib.a test_lib.o
cc $TARGET -DDECLSPEC_OUTER="" -DDECLSPEC_INNER="" -DEXTERN="extern" -DDIRECT -DEXE test.cc test_lib.a -o test.exe
./test.exe
echo ""
template <typename T>
struct DECLSPEC_OUTER outer {
static int *get_inner_sv_addr();
struct DECLSPEC_INNER inner {
static int sv;
};
};
template <typename T>
int *outer<T>::get_inner_sv_addr() { return &inner::sv; }
template <typename T>
int outer<T>::inner::sv = 0;
EXTERN template struct outer<int>;
#ifdef EXE
DECLSPEC_OUTER int *get_sv_addr();
#include <stdio.h>
#define S(s) SS(s)
#define SS(s) #s
int main() {
printf("DECLSPEC_OUTER='%s' DECLSPEC_INNER='%s' EXTERN='%s'\n sv=%p sv(via outer)=%p", S(DECLSPEC_OUTER), S(DECLSPEC_INNER), S(EXTERN), get_sv_addr(), outer<int>::get_inner_sv_addr());
#ifdef DIRECT
printf(" sv(direct)=%p\n", &outer<int>::inner::sv);
#else
printf("\n");
#endif
}
#else
DECLSPEC_OUTER int *get_sv_addr() { return &outer<int>::inner::sv; }
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment