标签: static-assert

G ++ vs Clang:constexpr和const的行为不一致

请考虑以下代码:

constexpr const int A = 42;

const int &B = A;
static_assert(&A == &B, "Bug");

constexpr const int &C = B;
static_assert(&A == &C, "Bug");

int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)

它完全被clang 3.3版所接受,而g ++(SUSE Linux)4.8.1 20130909 [gcc-4_8-branch revision 202388拒绝它:

bug2.cpp:5:1: error: non-constant condition for static assertion
 static_assert(&A == &B, "Bug");
 ^
bug2.cpp:5:1: error: the value of ‘B’ is not usable in a constant expression
bug2.cpp:2:12: note: ‘B’ was not declared ‘constexpr’
 const int &B = A;
            ^
Run Code Online (Sandbox Code Playgroud)

在我看来,海湾合作委员会是正确的(而我当然更喜欢铿锵行为).试图阅读标准我意识到我不够语言律师来决定.任何人都可以证实吗?

c++ static-assert language-lawyer constexpr c++11

5
推荐指数
1
解决办法
404
查看次数

POD中的static_assert是否会破坏POD?

我只是想知道......假设我在C++中有一个POD结构.如果我愿意放在static_assert那里,它会破坏这是一个POD的事实吗?

我知道我可以很容易地把它放在其他地方,我只是问,因为我感兴趣,如果我应该或不应该这样做......

换句话说(更具体):

#include <iostream>
#include <type_traits>

struct A 
{
    void* ptr;

    static_assert(sizeof(void*) == 8, "Pointer should have size 8; platform unsupported");
};

int main()
{
    // Is it guaranteed that this will evaluate to 'true'?
    std::cout << std::is_pod<A>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

c++ types assert static-assert

5
推荐指数
1
解决办法
403
查看次数

为什么这个"调用"断言看到两个参数而不仅仅是一个?

鉴于此测试计划:

#include <cassert>
#include <string>
#include <type_traits>

const std::string& const_string = "bla";
std::string const & string_const = "blabla";

static_assert(std::is_same<decltype(const_string), decltype(string_const)>::value, "Uhoh");

int main()
{
    assert(std::is_same<decltype(const_string), decltype(string_const)>::value);
}
Run Code Online (Sandbox Code Playgroud)

其中断言两种类型在编译时和使用C的断言在运行时是相同的.Clang,MSVC2015和GCC都报告了同样的错误,所以我很确定这是我:

main.cpp:13:49: error: too many arguments provided to function-like macro invocation
    assert(std::is_same<decltype(const_string), decltype(string_const)>::value);
                                                ^
/usr/include/assert.h:91:10: note: macro 'assert' defined here
# define assert(expr)                                                   \
         ^
Run Code Online (Sandbox Code Playgroud)

我只是没有看到两个论点assert.更重要的是,这些static_assert作品还不错......那么这里发生了什么?

c++ assert static-assert

5
推荐指数
1
解决办法
318
查看次数

static_assert用于任何类型的unique_ptr

我怎样才能静态断言表达式是一个std::unique_ptrstd::unique_ptr<T>任何T.

static_assert (std::is_pointer<decltype(exp)>()), "not a smart pointer")
Run Code Online (Sandbox Code Playgroud)

以上不起作用.如果没有直接的话,我只对bool()定义了类型的运算符感兴趣.

c++ static-assert

5
推荐指数
2
解决办法
767
查看次数

在静态断言和运行时错误之间自动选择

我有宏执行除法并检查对齐.

#define BYTES_TO_WORDS(x)  ((CHECK_ALIGNMENT(x,2)) * ((x) / 2))
Run Code Online (Sandbox Code Playgroud)

我想实现CHECK_ALIGNMENT一个总是返回1的宏,并且如果x不除以2 则触发错误.
BYTES_TO_WORDS从不同的上下文调用,有时x用作编译时常量整数表达式,有时x用作整数表达式这是在运行时解决的.

是否可以实现CHECK_ALIGNMENT,static_assert当使用常量表达式调用宏时,它将执行,并且当表达式不是编译时常量时,会检查一些运行时错误?
我可以更改宏定义,但不能更改宏的调用和使用方式.

这是一个可能的解决方案(并不总是有效):

#define CHECK_ALIGNMENT(x,alignedTo) (1/(((alignedTo)-((x)%(alignedTo)))/(alignedTo)))
Run Code Online (Sandbox Code Playgroud)

在此实现中,我们应该在运行时或编译时获得Division By Zero错误,具体取决于输入.
但是,由于编译器错误,这并不总是有效.此外,错误消息不是很好.

一个更好的解决方案是确定参数是否是编译时常量,并static_assert在这种情况下使用,编译时错误消息.如果参数不表示编译时常量,则检查运行时的对齐方式.

这可能吗?
我需要这个在Visual Studio 2015上工作.


澄清

关于为什么我在C++问题中使用宏,评论中有一些讨论.
所述BYTES_TO_WORDS宏是其中通过各种工具包括一个头文件,C++编译器是其中之一.
其他工具使用此宏并评估算术表达式((x) / 2),但在这些工具上我定义CHECK_ALIGNMENT为1,因为它们不能处理constexpr,模板甚至函数调用.
当用C++编译器编译这个头时,我想定义CHECK_ALIGNMENT一些其他东西,static_assert在需要时会触发或运行时错误.
定义CHECK_ALIGNMENT可以是任何C++ 11代码(或VS2015支持的C++ 14),可以使用模板,constexpr或诸如此类的东西.

c++ static-assert visual-c++ c++11 visual-studio-2015

5
推荐指数
1
解决办法
575
查看次数

编译时消息测试constexpr

当对编译时 constexpr 的测试评估为真时,是否可以打印消息?像 static_assert 这样的东西而不停止编译器。

constexpr Application::Mode SETUP_MODE = Application::Debug;

// Can I somehow test if the SETUP_MODE is debug for pragma message?
#pragma message("Application mode is set to Debug!")

static_assert(SETUP_MODE != Application::Debug, 
    "Application mode is set to Debug!"); // Can I somehow just print this message without aborting the compilation?
Run Code Online (Sandbox Code Playgroud)

c++ static-assert constexpr c++14

5
推荐指数
0
解决办法
598
查看次数

与static_assert和boost :: hana相关的Clang编译错误

考虑以下在Clang 3.8上成功编译的问题-std=c++14.

#include <boost/hana.hpp>

namespace hana = boost::hana;

int main() {
    constexpr auto indices = hana::range<unsigned, 0, 3>();
    hana::for_each(indices, [&](auto i) {
        hana::for_each(indices, [&](auto j) {
            constexpr bool test = (i == (j == i ? j : i));
            static_assert(test, "error");
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

测试是非常不敏感的,但这不是重点.现在考虑一个替代版本,其中测试直接放在static_assert:

#include <boost/hana.hpp>

namespace hana = boost::hana;

int main() {
    constexpr auto indices = hana::range<unsigned, 0, 3>();
    hana::for_each(indices, [&](auto i) {
        hana::for_each(indices, [&](auto j) {
            static_assert((i == (j == i ? j …
Run Code Online (Sandbox Code Playgroud)

c++ static-assert clang++ boost-hana

5
推荐指数
1
解决办法
511
查看次数

由于类型不完整,在 static_assert 中使用 std::is_base_of 失败

我想要做的是让一些类从一个extention类继承。问题是extention类必须知道它正在扩展哪个类。

这可以简单地实现如下:

template<typename Self>
class Extention
{
    public:
        void check() const
        {
            std::cout << "Extention is valid: "
                      << std::boolalpha
                      << std::is_base_of<Extention, Self>::value
                    << std::endl;
        }
};
class Foo : public Extention<Foo> {};
class Bar : public Extention<void> {};
Run Code Online (Sandbox Code Playgroud)

FooBar类节目好,进一步扩展的不好的用法。

Foo().check(); ? Extention is valid: true
Bar().check(); ? Extention is valid: false
Run Code Online (Sandbox Code Playgroud)

我想在编译时检查模板的有效性,这让我写了

template<typename Self>
class Extention
{
    static_assert(std::is_base_of<Extention, Self>::value);
};
Run Code Online (Sandbox Code Playgroud)

但是,gcc 告诉我这static_assert是错误的,因为class Foo类型不完整。

我究竟做错了什么 ?

编辑:我正在使用-std=c++17 …

c++ inheritance templates static-assert

5
推荐指数
1
解决办法
1343
查看次数

一个 static_assert 使另一个 static_assert 失败(内部类的 is_default_constructible)

以下代码编译:

struct Bar
{
    struct Foo
    {
        int v = 0;
    };

    // If uncomment the following line, both static assert will fail
    // static_assert(std::is_default_constructible_v<Foo>);
};

static_assert(std::is_default_constructible_v<Bar::Foo>);
Run Code Online (Sandbox Code Playgroud)

但是如果我取消注释 first static_assert,两者static_assert都会失败。这怎么会发生?

请参阅http://coliru.stacked-crooked.com/a/64e9c020056e37ed 中的代码

c++ static-assert inner-classes default-constructor type-traits

5
推荐指数
0
解决办法
38
查看次数

GCC 和 Clang 在与 __builtin_constant_p 相关的 static_assert 方面有所不同

我碰巧发现GCC和Clang在以下代码的编译上有所不同:

struct Foo
{
    int mem = 42;
};

int main()
{
    constexpr Foo foo;
    static_assert(__builtin_constant_p(foo));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用g++ -std=c++17和编译clang++ -std=c++17

特别是,

  • 加++ g++-9 (Homebrew GCC 9.3.0_1) 9.3.0编译,而
  • clang++Apple clang version 11.0.3 (clang-1103.0.32.62)无法编译,抱怨说
error: static_assert failed due to requirement '__builtin_constant_p(foo)'
    static_assert(__builtin_constant_p(foo));
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我没有发现任何关于__builtin_constant_p.

为了 __builtin_constant_p

海湾合作委员会

您可以使用内置函数 __builtin_constant_p 来确定某个值在编译时是否已知为常量...

叮当

Clang 支持许多与 GCC 语法相同的内置库函数,包括 __builtin_nan、__builtin_constant_p、__builtin_choose_expr、__builtin_types_compatible_p、__builtin_assume_aligned、__sync_fetch_and_add 等。

问题:虽然我知道__builtin_constant_p是一个编译器扩展,但哪个应该是正确的?

c++ g++ static-assert constexpr clang++

5
推荐指数
1
解决办法
210
查看次数