你正在使用的Go版本是什么( go version
)?
$ go version
go version go1.14.7 linux/amd64
这个问题在最新版本中是否重现?
尚未尝试
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build954734301=/tmp/go-build -gno-record-gcc-switches"
root@06ba4e8d3414:/go/src/bitbucket.org/threattrack/vipre-mac/foo#
你做了什么?
链接一个引用了 static const int
的程序,但在 undefined reference
上失败:foo.h
static const int BAR = 1;
foo.go
package main
/*
#include "foo.h"
*/
import "C"
import "fmt"
const (
BAR = int(C.BAR)
)
func main() {
fmt.Println(BAR)
}
你期望看到什么?
在linux上编译成功,就像在darwin上一样
你看到了什么?
go build
/usr/bin/ld: $WORK/b001/_cgo_main.o:/tmp/go-build/cgo-generated-wrappers:2: undefined reference to `BAR'
collect2: error: ld returned 1 exit status
6条答案
按热度按时间prdp8dxp1#
这似乎在
1.10.8
上起作用,但从1.11
开始停止工作。cc @ianlancetaylor
uqjltbpv2#
static
在 C 语言中表示它属于其编译单元。可以认为 C 和 Go 是不同的编译单元(我们确实分别对它们进行编译)。zqdjd7g93#
在这种情况下,推荐的方法是什么来保持Go常量与其C对应项同步 - 除了重新定义它们,这将是一个维护噩梦?
这段代码在darwin上编译和运行没有问题。
v7pvogib4#
我认为这也在 #39136 中提到了。一个区别是 GCC 为
BAR
生成了一个DW_AT_location
,而 clang 生成了一个DW_AT_const_value
。另一个区别是当编译这段代码时:clang 在没有错误的情况下编译了代码,但 GCC 报告了
我不确定为什么在这种情况下 clang 不会产生错误。clang 对于 C++ 的行为似乎是正确的,但对于 C 不是这样。
请注意,使用
#define
应该对这两个编译器都有效。ih99xse15#
我找到了破坏它的提交,da76981
0yg35tkg6#
已经过去3年了,有什么消息吗?