gcc 如何做可移植的64位算术,没有编译器警告

c86crjj0  于 2023-10-19  发布在  其他
关注(0)|答案(7)|浏览(181)

我偶尔会在我的一个开源C库中使用64位算法。我发现long long非常适合我的目的。甚至一些10年前的solaris box都能编译它。而且它在Windows上也不需要使用#defines。
现在的问题是,我收到了来自用户的投诉,因为他们使用GCC的迂腐设置进行编译,GCC坚持发出警告,说long long不是C
标准的一部分。这可能是对的,但我对C++标准本身并不太感兴趣,我只是希望我的代码能在尽可能多的编译器上工作。
所以我的问题是双重的:

  • 谁能说出不支持64位long的C++编译器的名字?
  • 有没有办法让GCC编译64位算术(在32位平台上)而没有编译器警告?(stdint. h没有帮助,因为它也依赖于long long

P.S.
如果有平台的多头变成128位或更大,这很有趣,但对我来说不是问题。

pod7payv

pod7payv1#

当你的库作为源代码提供时,一个选择是提供一个“移植”头,在这个头中,你的用户有责任提供一个64位类型(你指定名称)。那么,它们自然也有责任处理它们选择的类型所引发的任何编译器警告,要么避免它们,要么抑制它们,要么忽略它们。
我想这就是你所说的“在#defines上胡闹”,但我不认为这有太多的错。您可以提供一个默认版本,它只直接使用long long,并且可以在10年前的Solaris机器上工作,也可以在Windows上工作,因此大多数用户永远不需要接近您的库的用户可配置部分。
然后,对于学究式的用户,您可以提供一个包含<sys/types.h>的GCC版本,并使用int64_t而不是long long。对于g++ -pedantic来说,这并没有引起任何警告。你甚至可以在默认版本中通过识别GCC来做到这一点,它肯定会与#defines混淆,但同样,对于多平台产品来说,这并不罕见。
如果你的库在某些平台上也是以二进制文件的形式提供的,那么当然你必须决定64位类型是什么。如果它也出现在库接口中(因此也出现在头文件中),那么你只需要选择一个不会引起任何警告的合理的编译器选项。我认为-pedantic是一个合理的编译器选项,显然你的用户也是这样认为的,所以这也是GCC上的int64_t

zpgglvta

zpgglvta2#

在GCC中,使用-Wno-long-long编译器选项来消除该警告。
您也可以使用-std=C++0x,但可能会进一步降低可移植性。

mxg2im7a

mxg2im7a3#

如果你无法控制传递给gcc的开关,你可以用#pragma关闭警告。
http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html

hc2pp10m

hc2pp10m4#

您可以使用-Wno-long-long使警告静音(确保它在-pedantic之后出现)。C99和C++0x都需要64位整数,所以现在没有它们的编译器越来越少了。

insrf1ej

insrf1ej5#

您也可以使用gcc的“__extension__”功能来抑制警告,例如:

// No '-pedantic' warning/error.
__extension__ long long foo = 2;

// Exhibits '-pedantic' warning/error.
long long bar = 3

编译:

$ g++ -pedantic -fsyntax-only foo.cpp
foo.cpp:5: error: ISO C++ 1998 does not support 'long long'

请注意,只有最后一次使用long long触发了-pedantic错误,因为没有预先挂起__extension__。不管怎样,我还是同意@Steve Bullop的建议,使用int64_t

vwoqyblh

vwoqyblh6#

如果您在系统包含目录中有Boost,您可以说

#include "boost/cstdint.hpp"
boost::int64_t my_64_bit_number;

如果它位于系统包含目录中,则警告将自动隐藏。

7vux5j2d

7vux5j2d7#

您可以使用许多C++ bigint库中的一个来代替long long。我相信他们中的一些人避免了这个编译器错误。就我个人而言,我宁愿坚持错误。

相关问题