【发布时间】:2012-07-21 04:11:20
【问题描述】:
考虑以下示例代码:
#include <iostream>
#include <inttypes.h>
using namespace std;
int f(uint32_t i)
{
return 1;
}
int f(uint64_t i)
{
return 2;
}
int main ()
{
cout << sizeof(long unsigned) << '\n';
cout << sizeof(size_t) << '\n';
cout << sizeof(uint32_t) << '\n';
cout << sizeof(uint64_t) << '\n';
//long unsigned x = 3;
size_t x = 3;
cout << f(x) << '\n';
return 0;
}
这在 Mac OSX 上失败:
$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
$ make test
g++ test.cc -o test
test.cc: In function 'int main()':
test.cc:23: error: call of overloaded 'f(size_t&)' is ambiguous
test.cc:6: note: candidates are: int f(uint32_t)
test.cc:10: note: int f(uint64_t)
make: *** [test] Error 1
为什么?因为 'size_t' 应该是无符号的并且是 32 位或 64 位宽。那么歧义在哪里呢?
尝试使用 'unsigned long x' 而不是 'size_t x' 会导致 类似的歧义错误消息。
在 Linux/Solaris 系统上,使用不同的 GCC 版本、不同的体系结构等进行测试。没有报告歧义(并且每个体系结构都使用了正确的重载)。
这是 Mac OS X 的错误还是功能?
【问题讨论】:
-
不确定,但
size_t可能是签名类型 -
@BЈовић 否,标准要求
size_t未签名。 §18.2/6 说:“类型 size_t 是实现定义的无符号整数类型,它大到足以包含任何对象的字节大小。” -
虽然 gcc 有一段时间错误地将其作为有符号类型,但 IIRC。
-
另一个例子:
size_t r; /* ... */ boost::endian::big_to_native_inplace(r);。在 Linux/Solaris 上这有效,在 Mac OSX 上,由于歧义编译错误而中断 - 因为 boost::endian 只为固定宽度整数类型提供重载。另见:github.com/boostorg/endian/pull/14