【问题标题】:GCC 4.2.2 unsigned short error in castingGCC 4.2.2 转换中的无符号短错误
【发布时间】:2015-07-14 12:43:10
【问题描述】:

这行代码没有在 GCC 4.2.2 上为我编译

m_Pout->m_R[i][j] = MIN(MAX(unsigned short(m_Pin->m_R[i][j]), 0), ((1 << 15) - 1));

错误:“无符号”之前的预期主表达式

但是,如果我在(unsigned short) 中添加大括号,它就可以正常工作。

您能解释一下这里正在进行什么类型的转换(分配)吗?

为什么词法解析器/编译器不能理解 GCC 中的这个 c++ 代码?

您能否建议一种“更好”的方式来编写此代码?支持 GCC 4.2.2(无 c++11,跨平台)

【问题讨论】:

  • GCC 4.2 是一个非常古老的编译器 (2008)。请将其升级到较新的版本。您可以下载更新的版本(GCC 5.1,2015 年 7 月)并从其源代码编译。
  • @BasileStarynkevitch 如果由我决定的话......哦,如果只是...... :(
  • 为什么不能从它的源代码编译 GCC 5?您不需要任何 root 权限(仅在 GCC 5 构建树中 ..../gcc-5.1/configure --prefix=$HOME/soft --program-suffix=-mine...)然后是 make 然后是 make install
  • @BasileStarynkevitch:问题是 GCC 假设一个 glibc 版本,而 Linux 附带一个 glibc 版本。两者不一定相同,这可能会导致重大问题。在 Windows 上,微软已经明确表示不同的 MSVCRT 版本不是操作系统的一部分,并且从 7.0 开始,它们甚至命名不同,以便它们可以共存。
  • 如果你从源代码编译 GCC,它将适合你的 glibc。

标签: c++ gcc language-lawyer


【解决方案1】:
  1. unsigned short(m_Pin-&gt;m_R[i][j]) 是一个声明,它初始化了一个匿名临时变量,它不能是表达式的一部分。

  2. (unsigned short)(m_Pin-&gt;m_R[i][j]) 是一个 cast,而 is 是一个表达式。

所以 (1) 不能用作 MAX 的参数,但 (2) 可以。

【讨论】:

  • 但是为什么没有大括号它对 GCC 不起作用?
  • @Gilad:因为这就是 C++ 的语法。强制转换由表达式前面括号中的类型名表示。
  • 您能粘贴“带大括号”的案例吗?我第一次没有抓住它。除非你的意思是括号?
  • @Gilad:它就在那里(“2.”)。
  • @Bathsheba:技术上是括号...大括号:{}。括号:[]。括号:().
【解决方案2】:

我认为芭丝谢芭的回答至少具有误导性。 short(m_Pin-&gt;m_R[i][j]) 是一个演员。为什么额外的unsigned 搞砸了?这是因为unsigned short 不是简单类型说明符。转换语法 T(E) 仅在 T 是单个标记且 unsigned short 是两个标记时有效。

使用多个标记拼写的其他类型是 char*int const,因此这些类型也不是有效的类型转换:char*(0)int const(0)

使用static_cast&lt;&gt;&lt; &gt; 是平衡的,因此可以使用一系列标识符命名类型,甚至是static_cast&lt;int const*const&gt;(0)

【讨论】:

    【解决方案3】:

    您可以在 Bathsheba's answer 中使用 §2,但在 C++ 中使用 static_cast 更多 idiomatic

    static_cast<unsigned short>(m_Pin->m_R[i][j])
    

    顺便说一句,您的错误与 GCC 无关。如果使用Clang/LLVM 或任何(C++99 或 C++11)标准的 C++ 编译器,你会得到相同的结果。


    但除此之外,您应该使用更新版本的 GCC。 2015年7月的当前版本是GCC 5.1,而你的GCC 4.2.2版本是2007年的,非常古老。

    使用更新版本的 GCC 是值得的,因为:

    • 它使您能够坚持使用更新版本的 C++,例如C++11(使用-std=c++11-std=gnu++11 编译)

    • 最近的 GCC 改进了他们的诊断。使用-Wall -Wextra 编译会有很大帮助。

    • 最近的 GCC 优化得更好,您将从代码中获得更多性能

    • 最近的 GCC 有一个更好、更符合标准的标准 C++ 库

    • 最近的 GCC 更适合调试(使用最近的 GDB),并且有清理选项(-fsanitize=address-fsanitize=undefined、其他 -fsanitize=.... 选项),有助于发现错误

    • 最近的 GCC 更符合标准

    • 最近的 GCC 可以通过插件自定义,包括 MELT

    • FSF 不再支持旧的 GCC 4.2,您需要为支持它们的少数公司支付大笔费用。

    您不需要任何 root 访问权限即可从其源代码编译 GCC 5 编译器(或交叉编译器)。阅读installation 程序。您将构建一个适合您特定 libc 的 GCC(如果您愿意的话,您甚至可以使用 musl-libc....),也许通过在配置了命令之类的

     ...your-path-to/gcc-5/configure --prefix=$HOME/soft/ --program-suffix=-mine
    

    然后make 然后make install 然后将$HOME/soft/bin/ 添加到您的PATH 并使用gcc-mineg++-mine

    【讨论】:

      猜你喜欢
      • 2013-02-16
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      • 2011-09-29
      • 1970-01-01
      • 1970-01-01
      • 2015-10-21
      相关资源
      最近更新 更多