我正在尝试实现一些硬编码值的编译时验证.我有以下简化尝试:
using Type = std::initializer_list<int>;
constexpr bool all_positive(const Type& list)
{
bool all_positive = true;
for (const auto& elem : list)
{
all_positive &= (elem > 0);
}
return all_positive;
}
int main()
{
static constexpr Type num_list{ 1000, 10000, 100 };
static_assert(all_positive(num_list), "all values should be positive");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc编译它并完全按照我的预期工作,但是clang无法编译错误:
static_assert_test.cc:79:16: error: static_assert expression is not an integral constant expression
static_assert(all_positive(num_list), "all values should be positive");
^~~~~~~~~~~~~~~~~~~~~~
static_assert_test.cc:54:20: note: read of temporary is not allowed in a constant …Run Code Online (Sandbox Code Playgroud) 类似这个问题有关模板类的静态常量类成员明确分工,以及这个问题对模板类的明确分工,但我的问题是具有可变模板的显式特。
我的 MCVE:
//my_templated_literal.h
#pragma once
template <typename T>
constexpr T val;
Run Code Online (Sandbox Code Playgroud)
//my_specialised_literal.h
#pragma once
#include "my_templated_literal.h"
template <>
constexpr int val<int> = 2;
Run Code Online (Sandbox Code Playgroud)
//my_specialised_literal.h
#pragma once
#include "my_templated_literal.h"
template <>
constexpr int val<int> = 2;
Run Code Online (Sandbox Code Playgroud)
//main.cc
#include "my_specialised_literal.h"
int main() {}
Run Code Online (Sandbox Code Playgroud)
编译命令:$CXX -std=c++14 my_specialised_literal.cc main.cc
这可以编译并且似乎在我尝试过的几乎每个编译器版本上都按预期工作,但是会在使用 clang-9 时出现链接器错误:
/tmp/main-ec49c7.o:(.rodata+0x0):`val'的多重定义
/tmp/my_specialised_literal-521691.o:(.rodata+0x0): 这里首先定义
这是大多数编译器版本默默接受的 ODR 违规,还是 clang-9 在某种程度上是错误的?如果是前者,我知道如果我可以使用 C++17,我可以通过进行 specialization 来修复它inline,但是什么是 C++14 修复问题?
在尝试找出为什么会出现某个编译错误时,我想出了以下最小示例:
\n\nconstexpr void Test(bool test)\n{\n if (test)\n return;\n\n assert(false);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我尝试过的每个版本的 clang (3.7+) 都可以毫无问题地进行编译,但使用 gcc 会失败(测试了 5-8),
\n\n\n\n\n错误:调用非\xe2\x80\x98constexpr\xe2\x80\x99函数\xe2\x80\x98void __assert_fail(const\n char*, const char*, unsigned int, const char*)\xe2\x80\x99
\n
根据我的理解,该函数应该能够constexpr,因为可以在编译时评估该函数的一组参数值。
是我的理解错误,还是gcc编译失败而错误?
\nI decided to test compile a project with -Wsign-conversion enabled, to see what warnings would come up, and came across something that doesn't seem right, where gcc behaves differently than clang. Can someone please tell me which is correct?
I have a function that takes a size_t param:
void func(size_t) {}
Run Code Online (Sandbox Code Playgroud)
some other struct
struct Test {};
Run Code Online (Sandbox Code Playgroud)
and calling code
int i = some_initialiser();
func(sizeof(Test) + static_cast<size_t>(i));
Run Code Online (Sandbox Code Playgroud)
So from my understanding, sizeof returns size_t, and arithmetic between two variables …