gpt4 book ai didi

gcc - 构造一个 'long long'

转载 作者:行者123 更新时间:2023-12-04 19:15:15 28 4
gpt4 key购买 nike

你如何构建一个 long long在 gcc 中,类似于构造 int通过 int()
以下在 gcc (4.6.3 20120306) 中失败(但例如通过 MSVC)。

myFunctionCall(someValue, long long());

有错误 expected primary-expression before 'long' (列位置表示第一个长是位置)。

一个简单的改变
myFunctionCall(someValue, (long long)int());

工作正常 - 那就是构造一个 int并转换为 long long - 表示 gcc 不喜欢 long long医生。

总结解决方案

总结以下来自@birryree 的精彩解释:
  • 许多编译器不支持long long()它可能不符合标准
  • build long long相当于文字 0LL , 所以使用 myFunctionCall(someValue, 0LL)
  • 或者使用 typedef long_long_t long long然后 long_long_t()
  • 最后,考虑使用 uint64_t如果您在任何平台上追求一种正好是 64 位的类型,而不是至少 64 位的类型,但在不同平台上可能会有所不同。
  • 最佳答案

    我想要一个关于预期行为的明确答案,所以我 posted a question on comp.lang.c++.moderated 并得到了一些很好的答案作为返回。 感谢 Johannes Schaub、Alf P. Steinbach(均来自 SO)和 Francis Glassborrow 提供一些信息

    这不是 GCC 中的错误 - 实际上它会跨越多个编译器 - GCC 4.6、GCC 4.7 和 Clang 提示类似的错误,如 primary expression expected before '('如果你试试这个语法:

    long long x = long long();

    一些原语有空格,如果你想使用构造函数风格的初始化,因为绑定(bind)是不允许的( long() 是绑定(bind)的,但是 long long() 有一个免费的 long )。带有空格的类型(如 long long )不能使用 type() -施工形式。

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

    解决方案/解决方法

    您想要做的事情有其他选择:
  • 使用0LL作为您的值(value),而不是尝试long long() - 他们会产生相同的值(value)。

    这也是大多数代码的编写方式,因此其他阅读您的代码的人最容易理解。
  • 从你的评论看来你真的想要long long , 所以你可以 typedef自己始终保证您拥有long long输入,像这样:
    int main() {
    typedef long long MyLongLong;
    long long x = MyLongLong(); // or MyLongLong x = MyLongLong();
    }
  • 使用模板来解决需要显式命名的问题:
    template<typename TypeT>
    struct Type { typedef TypeT T(); };

    // call it like this:
    long long ll = Type<long long>::T();
  • 正如我在评论中提到的,您可以使用别名类型,例如 int64_t (来自 <cstdint> ),跨常见平台是 typedef long long int64_t .这比此列表中的前面的项目更依赖于平台。
    int64_t是 64 位的固定宽度类型,通常是 long long 的宽度在 linux-x86 和 windows-x86 等平台上。 long long至少 64 位宽,但可以更长。如果您的代码只能在某些平台上运行,或者您确实需要固定宽度的类型,那么这可能是一个可行的选择。

  • C++11 解决方案

    感谢 C++ 新闻组,我学到了一些额外的方法来做你想做的事情,但不幸的是,它们只在 C++11 的领域内(MSVC10 也不支持,而且只有非常新的编译器会):
  • {}方式:
    long long ll{}; // does the zero initialization
  • 使用 Johannes 所说的 C++11 中的“边框工具”和 std::common_type<T>
    #include <type_traits>

    int main() {
    long long ll = std::common_type<long long>::type();
    }


  • 那么 () 之间有真正的区别吗?并使用 0 进行初始化对于 POD 类型?

    你在评论中这样说:

    I don't think default ctor returns zero always - more typical behaviour is to leave memory untouched.



    好吧,对于原始类型,这根本不是真的。

    来自 第 8.5 节 ISO C++ 标准/2003(没有 2011,抱歉,但此信息没有太大变化):

    To default-initialize an object of type T means:

    — if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

    — if T is an array type, each element is default-initialized;

    otherwise, the object is zero-initialized.



    最后一个子句在这里最重要,因为 long long , unsigned long , int , float等都是标量/POD类型,所以调用这样的东西:
    int x = int();

    与这样做完全相同:
    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) >>>>>;
    }

    生成的代码含义

    因此,从上面生成的代码树中,请注意我所有的变量都只是用 0 初始化。 ,即使我使用构造函数样式的默认初始化,例如 int mi = int() . GCC 将生成只执行 int mi = 0 的代码.

    我的模板函数只是尝试对传入的一些 typename T 进行默认构造, 其中 T = unsigned long long , 也只产生了一个 0 - 初始化代码。

    结论

    所以总而言之,如果你想默认构造原始类型/POD,就像使用 0 .

    关于gcc - 构造一个 'long long',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10527441/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com