使用常量从模板基类 [英] using constant from template base class

查看:111
本文介绍了使用常量从模板基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码不在g ++ 5.3.1下编译,而是在clang 3.7.0下编译。哪个编译器是正确的?

  [hidden] cat c.cpp 
template< typename T>
struct Base {
constexpr static int Align_ = alignof(T);
};

template< typename T>
struct Derived:Base< T> {
using Base_ = Base< T> ;;
using Base _ :: Align_;
alignas(Align_)char buf [1];
};

编译输出:

  [hidden] clang ++ -c -std = c ++ 14 c.cpp 
[hidden] g ++ -c -std = c ++ 14 c.cpp
c.cpp: 10:29:error:请求的对齐不是一个整数常量
alignas(Align_)char buf [1];
^
[hidden]
[hidden] g ++ -v
使用内置规格。
COLLECT_GCC = / usr / bin / g ++
COLLECT_LTO_WRAPPER = / usr / libexec / gcc / x86_64-redhat-linux / 5.3.1 / lto-wrapper
目标:x86_64-redhat-linux
配置:../configure --enable-bootstrap --enable-languages = c,c ++,objc,obj-c ++,fortran,ada,go,lto --prefix = / usr --mandir = / usr / share / man --infodir = / usr / share / info --with-bugurl = http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads = posix --enable-checking = release --enable-multilib --with-system-zlib --enable -__ cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker- style = gnu --enable-plugin --enable-initfini-array --disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function --with-tune = generic --with- arch_32 = i686 --build = x86_64-redhat-linux
线程模型:posix
gcc版本5.3.1 20151207(Red Hat 5.3.1-2)(GCC)
[hidden]
[hidden] clang ++ -v
clang版本3.7.0(http://llvm.org/git/clang.git 2ddd3734f32e39e793550b282d44fd71736f8d21)
目标:x86_64-unknown-linux-gnu
线程模型:posix
找到的候选GCC安装:/usr/lib/gcc/x86_64-redhat-linux/3.4.6
找到的候选GCC安装:/ usr / lib / gcc / x86_64-redhat- linux / 5.3.1
选择的GCC安装:/usr/lib/gcc/x86_64-redhat-linux/5.3.1
候选multilib:。; @ m64
候选multilib:32; @ m32
选择的multilib:。; @ m64


解决方案

它看起来像GCC中的一个错误,因为它应该按标准工作。从标准草稿n4567


当对齐标识符的形式是alignas( constant-expression ):

(2.1) - 常量表达式 必须是一个整数常数表达式



(2.2) - 如果常量表达式没有求值为对齐值(3.11),或者计算为扩展的
对齐,并且实现不支持


在您的情况下,您正在提供一个整数常量表达式。只有当常数表达式不满足这个条件时才会失败。


对齐表示为类型std的值: :size_t。有效的对齐方式只包括基本类型的alignof表达式返回的值
和一个附加的实现定义的集合
的值,它们可能为空。每个对齐值都应为2的非负整数。



扩展对齐由大于alignof(std :: max_align_t)的对齐表示。它是
实现定义是否支持任何扩展对齐和支持它们的上下文
(7.6.2)。具有扩展对准要求的类型是过度对准类型。 [注意:
每个过对齐的类型是或包含一个类类型,扩展对齐适用(可能通过
非静态数据成员)。



The following piece of code doesn't compile under g++ 5.3.1 but compiles under clang 3.7.0. Which compiler is correct?

[hidden] cat c.cpp
template <typename T>
struct Base {
  constexpr static int Align_ = alignof(T);
};

template <typename T>
struct Derived : Base<T> {
  using Base_ = Base<T>;
  using Base_::Align_;
  alignas(Align_) char buf[1];
};

Compile output:

[hidden] clang++ -c -std=c++14 c.cpp
[hidden] g++ -c -std=c++14 c.cpp
c.cpp:10:29: error: requested alignment is not an integer constant
   alignas(Align_) char buf[1];
                             ^
[hidden]
[hidden] g++ -v
Using built-in specs.
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
[hidden]
[hidden] clang++ -v
clang version 3.7.0 (http://llvm.org/git/clang.git 2ddd3734f32e39e793550b282d44fd71736f8d21)
Target: x86_64-unknown-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/3.4.6
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/5.3.1
Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/5.3.1
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64

解决方案

It looks like a bug in GCC because it should work by standard. From the standard draft n4567

When the alignment-specifier is of the form alignas( constant-expression ):

(2.1) — the constant-expression shall be an integral constant expression

(2.2) — if the constant expression does not evaluate to an alignment value (3.11), or evaluates to an extended alignment and the implementation does not support that alignment in the context of the declaration, the program is ill-formed.

In your case you are supplying an integral constant expression.This could fail only if when evaluated the constant expression does not satisfy this

Alignments are represented as values of the type std::size_t. Valid alignments include only those values returned by an alignof expression for the fundamental types plus an additional implementation-defined set of values, which may be empty. Every alignment value shall be a non-negative integral power of two.

An extended alignment is represented by an alignment greater than alignof(std::max_align_t). It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported (7.6.2). A type having an extended alignment requirement is an over-aligned type. [ Note: every over-aligned type is or contains a class type to which extended alignment applies (possibly through a non-static data member).

这篇关于使用常量从模板基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆