Gcc 构建一个';长-长';

Gcc 构建一个';长-长';,gcc,Gcc,如何在gcc中构造long,类似于通过int()构造int 以下内容在gcc(4.6.3 20120306)中失败(但以MSVC为例) 错误在“long”之前应该有主表达式(列位置指示第一个long是位置) 一个简单的改变 myFunctionCall(someValue, (long long)int()); 工作正常-即构造一个int并转换为long-表示gcc不喜欢long选择器 摘要解决方案 总结一下@Birryrree的精彩解释: 许多编译器不支持long() 构造long-lon

如何在gcc中构造
long
,类似于通过
int()构造
int

以下内容在gcc(4.6.3 20120306)中失败(但以MSVC为例)

错误
在“long”之前应该有主表达式(列位置指示第一个long是位置)

一个简单的改变

myFunctionCall(someValue, (long long)int());
工作正常-即构造一个
int
并转换为
long
-表示gcc不喜欢
long
选择器

摘要解决方案 总结一下@Birryrree的精彩解释:

  • 许多编译器不支持
    long()
  • 构造
    long-long
    相当于文本
    0LL
    ,因此使用
    myFunctionCall(someValue,0LL)
  • 或者使用
    typedef long\u long\u t long
    然后使用
    long\u long\u t()
  • 最后,请考虑使用<代码> UTIT64×T/<代码>,如果您在任何平台上都是一个64位的类型,而不是一个至少64位的类型,但可能在不同的平台上有所不同。
我想要一个关于预期行为的明确答案,因此我得到了一些很好的回答。因此,我要感谢Johannes Schaub、Alf p.Steinbach(均来自so)和Francis Glassborrow,以获取一些信息

这不是GCC中的错误-事实上,它会在多个编译器之间中断-GCC 4.6、GCC 4.7和Clang抱怨类似的错误,如“(”
如果您尝试以下语法,则在“(”
之前预期的主表达式):

long long x = long long();
有些原语有空格,如果您想使用构造函数样式的初始化,这是不允许的,因为绑定(
long()
是绑定的,但是
long()
有一个自由的
long
)中有空格的类型(如
long-long
)不能使用
type()
-构造表单

MSVC在这里更为宽容,尽管在技术上不符合标准(而且它不是一个可以禁用的语言扩展)

解决方案/变通办法 对于您想做的事情,有多种选择:

  • 使用
    0LL
    作为您的值,而不是尝试
    long long()
    ——它们将产生相同的值

    这也是大多数代码的编写方式,因此阅读您的代码的其他人最容易理解

  • 从您的评论来看,您似乎真的想要
    long
    ,因此您可以
    typedef
    自己始终保证您拥有
    long
    类型,如下所示:

    int main() {
        typedef long long MyLongLong;
        long long x = MyLongLong(); // or MyLongLong x = MyLongLong();
    }
    
    int x = int();
    
  • 使用模板绕过需要显式命名的问题:

    template<typename TypeT>
    struct Type { typedef TypeT T(); };
    
    // call it like this:
    long long ll = Type<long long>::T();
    
  • 使用Johannes在C++11中所称的“bord工具”和
    std::common_type

    与执行此操作完全相同:

    int x = 0;
    

    生成的代码示例 下面是一个更具体的示例,说明代码中实际发生的情况:

    #include <iostream>
    
    template<typename T>
    void create_and_print() {
       T y = T();
       std::cout << y << std::endl;
    }
    
    int main() {
       create_and_print<unsigned long long>();
    
       typedef long long mll;
       long long y = mll();
       long long z = 0LL;
    
       int mi = int();
    }
    
    我在生成的树转储中得到:

    ;; Function int main() (null)
    ;; enabled by -tree-original
    
    {
      typedef mll mll;
      long long int y = 0;
      long long int z = 0;
      int mi = 0;
    
      <<cleanup_point <<< Unknown tree: expr_stmt
      create_and_print<long long unsigned int> () >>>>>;
      <<cleanup_point   long long int y = 0;>>;
      <<cleanup_point   long long int z = 0;>>;
      <<cleanup_point   int mi = 0;>>;
    }
    return <retval> = 0;
    
    
    
    ;; Function void create_and_print() [with T = long long unsigned int] (null)
    ;; enabled by -tree-original
    
    {
      long long unsigned int y = 0;
    
      <<cleanup_point   long long unsigned int y = 0;>>;
      <<cleanup_point <<< Unknown tree: expr_stmt
      (void) std::basic_ostream<char>::operator<< ((struct __ostream_type *) std::basic_ostream<char>::operator<< (&cout, y), endl) >>>>>;
    }
    
    ;;函数int main()(空)
    ;;由原始树启用
    {
    类型定义mll mll;
    长整型y=0;
    长整型z=0;
    int-mi=0;
    >;
    ;
    ;
    ;
    }
    返回=0;
    ;函数void create_and_print()[with T=long unsigned int](null)
    ;;由原始树启用
    {
    长无符号整数y=0;
    ;
    
    您可以使用
    int64\u t()
    而不是
    long()
    -它是一个
    typedef
    long
    ,更清楚地表明它是一个64位整数。我们能保证int64\u t的位数总是与long相同吗?
    int64\u t
    保证64位,而
    long
    至少是64位。另一种可以创建int作为特定类型的方法是指定t类型后缀,如
    0LL
    。严格来说,没有一个与默认的长-长构造相同,但int64_t和
    0LL
    都是非常好的解决方法-至少足以让我编译。默认的整数类型构造会将
    0
    作为值返回。然而,它不是真正的构造函数从某种意义上说,类有构造函数,
    ()
    看起来像构造函数,但使用的是
    int()和刚才提到的<代码> int x=0 < /代码>是一样的。在C++中有一个奇怪的东西,就是模板支持。注意在<代码> CSTINT/<代码> Stdit.H.<代码>,<代码> INT64×T < /COD>是一个<代码> Type f长的长/代码>,但是如果你真的需要你自己来保证它,你就可以制作自己的TyPuff,比如<代码> TyPulfLon。g long MyLongLong
    并执行此操作
    MyLongLong()
    。如果答案不是关于“long long”和“uint64\u t”是“通常相同”的,它实际上将其列为第一个“解决方案”,我会给出+1.几十年来,我们一直试图教育程序员不要对int、long或long-long的宽度做出假设,这就是为什么
    被发明的原因…@DevSolar-我不打算给列表任何有序的权重,但我可以看到它是如何被解释的。我将编辑它以强调常见的解决方案。感谢您的努力-tha(现在很明显,
    int i;
    int i=int()
    是不一样的……我真傻!)另外,好的编辑re:uint64\u t,我认为这一点很重要。也许在30年后使用
    将成为常态。。。
    int x = 0;
    
    #include <iostream>
    
    template<typename T>
    void create_and_print() {
       T y = T();
       std::cout << y << std::endl;
    }
    
    int main() {
       create_and_print<unsigned long long>();
    
       typedef long long mll;
       long long y = mll();
       long long z = 0LL;
    
       int mi = int();
    }
    
    g++ -fdump-tree-original construction.cxx
    
    ;; Function int main() (null)
    ;; enabled by -tree-original
    
    {
      typedef mll mll;
      long long int y = 0;
      long long int z = 0;
      int mi = 0;
    
      <<cleanup_point <<< Unknown tree: expr_stmt
      create_and_print<long long unsigned int> () >>>>>;
      <<cleanup_point   long long int y = 0;>>;
      <<cleanup_point   long long int z = 0;>>;
      <<cleanup_point   int mi = 0;>>;
    }
    return <retval> = 0;
    
    
    
    ;; Function void create_and_print() [with T = long long unsigned int] (null)
    ;; enabled by -tree-original
    
    {
      long long unsigned int y = 0;
    
      <<cleanup_point   long long unsigned int y = 0;>>;
      <<cleanup_point <<< Unknown tree: expr_stmt
      (void) std::basic_ostream<char>::operator<< ((struct __ostream_type *) std::basic_ostream<char>::operator<< (&cout, y), endl) >>>>>;
    }