代码用g ++编译,但不用arm-none-eabi-g ++编译

时间:2014-04-17 07:18:26

标签: c++ c++11 g++ arm bare-metal

我一直在尝试更改一些语法,强制用户在访问之前在我编写的STM32F4 Cortex-M4 CPU的简单库中启用外设时钟。

在努力使用以下代码不能工作几个小时后,我无法找到我做错的事情,并试图用linux g ++编译它,它成功了。

这是关于ARM g ++的编译器错误,还是我一直在使用linux g ++允许我使用的一些非标准行为?

这是一个简化的代码示例:

#include <cstdint>

template<std::size_t port>
class Port
{
public: //Declarations
  enum class PinMode
  {
    Input = 0x0,
    Output = 0x1,
    Alternate = 0x2,
    Analog = 0x3
  };

  template<uint8_t nPin, PinMode mode>
  class Pin
  {

  };

  template<uint8_t nPin>
  class Pin<nPin, PinMode::Output>
  {
  public: //Declarations
    enum class OutputSpeed : uint32_t
    {
      Low,
      Medium,
      Fast,
      High
    };

    enum class PullMode : uint32_t
    {
      None = 0x0,
      PullUp = 0x1,
      PullDown = 0x2
    };

  public: //Methods
    void setOutputSpeed(OutputSpeed const ospeed) volatile;
    void setPullMode(PullMode const ppm) volatile;

    void set() volatile
    {
      reinterpret_cast<Port<port> volatile*>(port)->m_BSRR |= static_cast<uint16_t>(0x1) <<nPin;
    }
    void reset() volatile;

    bool getOutputState() volatile;
  }; //END OutputPin

public: //Registers
  uint32_t m_BSRR;
}; //END Port

int main()
{
  auto pin = Port<0>::Pin<5, Port<0>::PinMode::Output>();
  pin.set();
}

ARM g ++输出。

Using built-in specs.
COLLECT_GCC=arm-none-eabi-g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-none-eabi/4.8.2/lto-wrapper
Target: arm-none-eabi
Configured with: ../configure --target=arm-none-eabi --prefix=/usr --libexecdir=/usr/lib --with-pkgversion='Arch Repository' --with-bugurl=https://bugs.archlinux.org/ --enable-multilib --enable-interwork --enable-languages=c,c++ --with-newlib --with-gnu-as --with-gnu-ld --disable-nls --disable-shared --disable-threads --with-headers=newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp --with-system-zlib --disable-newlib-supplied-syscalls
Thread model: single
gcc version 4.8.2 (Arch Repository) 
COLLECT_GCC_OPTIONS='-std=c++11' '-v'
 /usr/lib/gcc/arm-none-eabi/4.8.2/cc1plus -quiet -v -D__USES_INITFINI__ test.cpp -quiet -dumpbase test.cpp -auxbase test -std=c++11 -version -o /tmp/cc6TlpeV.s
GNU C++ (Arch Repository) version 4.8.2 (arm-none-eabi)
    compiled by GNU C version 4.8.2 20140206 (prerelease), GMP version 5.1.3, MPFR version 3.1.2-p5, MPC version 1.0.2
warning: GMP header version 5.1.3 differs from library version 6.0.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-eabi/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-eabi/include/c++/4.8.2
 /usr/lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-eabi/include/c++/4.8.2/arm-none-eabi
 /usr/lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-eabi/include/c++/4.8.2/backward
 /usr/lib/gcc/arm-none-eabi/4.8.2/include
 /usr/lib/gcc/arm-none-eabi/4.8.2/include-fixed
 /usr/lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-eabi/include
End of search list.
GNU C++ (Arch Repository) version 4.8.2 (arm-none-eabi)
    compiled by GNU C version 4.8.2 20140206 (prerelease), GMP version 5.1.3, MPFR version 3.1.2-p5, MPC version 1.0.2
warning: GMP header version 5.1.3 differs from library version 6.0.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 8ead046d6b54a8fe43e9a23d5562e5d4
test.cpp: In function 'int main()':
test.cpp:60:7: error: 'class Port<0u>::Pin<5u, (Port<0u>::PinMode)1>' has no member named 'set'
   pin.set();
       ^

G ++输出:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/gcc/src/gcc-4.8-20140206/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl --disable-cloog-version-check --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --disable-multilib --disable-werror --enable-checking=release
Thread model: posix
gcc version 4.8.2 20140206 (prerelease) (GCC) 
COLLECT_GCC_OPTIONS='-std=c++11' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/cc1plus -quiet -v -D_GNU_SOURCE test.cpp -quiet -dumpbase test.cpp -mtune=generic -march=x86-64 -auxbase test -std=c++11 -version -o /tmp/ccgCeLLA.s
GNU C++ (GCC) version 4.8.2 20140206 (prerelease) (x86_64-unknown-linux-gnu)
    compiled by GNU C version 4.8.2 20140206 (prerelease), GMP version 5.1.3, MPFR version 3.1.2-p5, MPC version 1.0.2
warning: GMP header version 5.1.3 differs from library version 6.0.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../x86_64-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/x86_64-unknown-linux-gnu
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/backward
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/include
 /usr/local/include
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/include-fixed
 /usr/include
End of search list.
GNU C++ (GCC) version 4.8.2 20140206 (prerelease) (x86_64-unknown-linux-gnu)
    compiled by GNU C version 4.8.2 20140206 (prerelease), GMP version 5.1.3, MPFR version 3.1.2-p5, MPC version 1.0.2
warning: GMP header version 5.1.3 differs from library version 6.0.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 51ac5eb9b6c30af2da1950e6dfed6398
COLLECT_GCC_OPTIONS='-std=c++11' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccWIQqrr.o /tmp/ccgCeLLA.s
GNU assembler version 2.24 (x86_64-unknown-linux-gnu) using BFD version (GNU Binutils) 2.24
COMPILER_PATH=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-std=c++11' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/collect2 --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crt1.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crti.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/crtbegin.o -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2 -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../.. /tmp/ccWIQqrr.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/crtend.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crtn.o

2 个答案:

答案 0 :(得分:1)

不是真正的答案&#34;,但写入评论的文字太多了。我在g ++ 4.8.2 for x86-64中看到了同样的问题(从源代码开始,在结束时或3月初/ 4月初)。

似乎编译器正在拾取您的通用模板,而不是专用模板。

  template<uint8_t nPin, PinMode mode>
  class Pin
  {

  };

确实没有set成员。如果我在该类中添加set成员,则代码将编译。我不确定为什么编译器认为使用它比专门的类更好。我怀疑它是4.8.2中的一个错误。

(我注意到你的g ++ 4.8.2 for x86-64是&#34;预发布&#34;,这可以解释为什么它在两种体系结构上有所不同)。

它在clang ++ 3.5(截至昨天的不稳定分支)和g ++ 4.6.3中编译。它不能用clang ++ 2.9编译。

答案 1 :(得分:1)

您的代码中存在两个问题。

不确定原因,但在模板中使用枚举类不能正常工作。由于它是模板和新c ++功能的基础案例,因此很难在标准中找到禁止它的确切位置。它甚至可能是编译器错误。

所以,固定代码如下:

#include <cstdint>

  enum class PinMode
  {
    Input = 0x0,
    Output = 0x1,
    Alternate = 0x2,
    Analog = 0x3
  };
    enum class OutputSpeed : uint32_t
    {
      Low,
      Medium,
      Fast,
      High
    };

    enum class PullMode : uint32_t
    {
      None = 0x0,
      PullUp = 0x1,
      PullDown = 0x2
    };

template<std::size_t port>
class Port
{
public: //Declarations


  template<uint8_t nPin, PinMode mode>
  class Pin;

  template<uint8_t nPin>
  class Pin<nPin, PinMode::Output>
  {

  public: //Methods
    void setOutputSpeed(OutputSpeed const ospeed) volatile;
    void setPullMode(PullMode const ppm) volatile;

    void set() volatile
    {
      reinterpret_cast<Port<port> volatile*>(port)->m_BSRR |= static_cast<uint16_t>(0x1) <<nPin;
    }
    void reset() volatile;

    bool getOutputState() volatile;
  }; //END OutputPin

public: //Registers
  uint32_t m_BSRR;
}; //END Port

int main()
{
    auto pin = Port<0>::Pin< 5, PinMode::Output >();
  pin.set();
}