标准说:
"一个值为 0 的整数常量表达式,或这样一个转换为 type 的表达式
void*,称为空指针常量.67) 如果将空指针常量转换为指针类型,则保证得到的指针称为空指针比较不等于指向任何对象或函数的指针。”
" 67) 宏 NULL 在 stddef.h(和其他头文件)中定义为空指针常量;见 7.19。 "
来源:ISO/IEC 9899:2018 (C18),第 6.2.3.2/3 节“指针”。
最常见的空指针常量当然是最常见的,0并且(void*) 0被大多数实现用作空指针常量,但作为标准要求 - “值为 0 的整数常量表达式,或这样的表达式转换为类型void*” -空指针常量应也可以是以下任何一种:
1 * 00 * 00 - 025 - 25(-4) + (4)(0 * ((0 * 25) * 3)(0) * (-100)就像他们前面有(void*), fe(void*) (1 * 0) …
C定义了至少3个级别的"常量表达式":
6.6第3段内容如下:
常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中.
那么这意味着1,2不是一个恒定的表达式吗?
第8段内容如下:
算术常量表达式应具有算术类型,并且只能具有整数常量,浮点常量,枚举常量,字符常量和sizeof表达式的操作数.算术常量表达式中的转换运算符只能将算术类型转换为算术类型,除非作为sizeof运算符的操作数的一部分,其结果为整数常量.
什么是操作数(union { uint32_t i; float f; }){ 1 }.f?如果1是操作数,那么这可能是一个算术常量表达式,但如果{ 1 }是操作数,则显然不是.
编辑:另一个有趣的观察:7.17第3段要求结果是offsetof类型的整数常量表达式size_t,但offsetof据我所知,标准实现不需要是标准的整数常量表达式.这当然是可以的,因为允许实现(在6.6第10段下)接受其他形式的常量表达式,或者实现offsetof宏__builtin_offsetof而不是通过指针减法.但是,这种观察的本质是,如果你想offsetof在需要整数常量表达式的上下文中使用,你真的需要使用实现提供的宏而不是自己的.
clang(trunk) 给出以下代码的错误:
consteval void f() {}
int main()
{
f(); // error: call to consteval function 'f' is not a constant expression
// note: subobject of type 'void' is not initialized
}
Run Code Online (Sandbox Code Playgroud)
而 gcc(trunk) 编译它没有错误。
我觉得这可能是一个 clang bug,因为 gcc 和 clang 都接受这个代码:
consteval int g() { return 42; }
int main()
{
g(); // ok
}
Run Code Online (Sandbox Code Playgroud)
这是要玩的代码。
那么这是一个 clang bug,还是代码格式不正确,或者有 ub,还是其他什么?
编辑:我觉得指出 clang 允许f从其他函数调用(如果它们也是保守的)可能是相关的。f它仅在从非 consteval 函数调用时给出错误:
consteval int h()
{
f(); // ok
return 42; …Run Code Online (Sandbox Code Playgroud) 问题标题的措辞可能不正确,我会很乐意根据您的建议进行修复。
我的问题可以用这个片段来说明:
#include <array>
template <typename Callable>
constexpr auto make_array_ok(Callable callable) {
return std::array<int, callable()>{};
};
// constexpr auto make_array_bad(std::size_t s)
// {
// return std::array<int,s>{};
// };
int main(int argc, char**) {
static_cast<void>(argc);
auto size = []() { return std::size_t{42}; };
// fails to compile -- as I expected
// auto size_dyn = [argc]() { return std::size_t(argc); };
// auto a = make_array_ok(size_dyn);
// also fails to compile -- but why?
// auto size_capt = [arg = size()]()constexpr{return arg;}; …Run Code Online (Sandbox Code Playgroud) 为什么这个C代码在Visual Studio 2013 Ultimate中是非法的?
const unsigned int x = 64;
char resultBufNative[x+1];
Run Code Online (Sandbox Code Playgroud)
它给出了error C2057: expected constant expression.
我完全被这个困惑了.
相关功能:
jstring Java_com_nabto_api_NabtoCApiWrapper_nabtoGetSessionToken(JNIEnv* env, jclass thiz, jobject sessionObj)
{
const size_t size = 64;
char resultBufNative[size+1];
size_t resultLen;
//Get the session
nabto_handle_t session;
session = (nabto_handle_t) (*env)->GetDirectBufferAddress(env, sessionObj);
nabto_status_t nabtoStatus = nabtoGetSessionToken(session, resultBufNative, size, &resultLen);
if (nabtoStatus == NABTO_OK && resultLen <= size) {
// Terminate char array, convert to java string, free buffer and return result
resultBufNative[resultLen] = …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <fstream>
#include <cmath>
#include <math.h>
#include <iomanip>
using std::ifstream;
using namespace std;
int main (void)
{
int count=0;
float sum=0;
float maximum=-1000000;
float sumOfX;
float sumOfY;
int size;
int negativeY=0;
int positiveX=0;
int negativeX=0;
ifstream points; //the points to be imported from file
//points.open( "data.dat");
//points>>size;
//cout<<size<<endl;
size=100;
float x[size][2];
while (count<size) {
points>>(x[count][0]);
//cout<<"x= "<<(x[count][0])<<" ";//read in x value
points>>(x[count][1]);
//cout<<"y= "<<(x[count][1])<<endl;//read in y value
count++;
}
Run Code Online (Sandbox Code Playgroud)
这个程序在我声明浮动x [大小] [2]的行上给出了预期的常量表达式错误.为什么?
众所周知,必须确定C++中的数组长度.然后我们可以使用:
const int MAX_Length=100;
Run Code Online (Sandbox Code Playgroud)
要么:
#define MAX_LENGTH 100
Run Code Online (Sandbox Code Playgroud)
在编译之前确定数组的长度.但是,当我读到lippman的书c ++入门时,在第5版的第3.5.1节中,它说:数组的长度必须是一个常量表达式.然后问题来了:
typedef enum Length{LEN1=100, LEN2, LEN3, LEN4}LEN;
LEN MAX_Length=LEN2; //101
int iArray[LEN2]; //attention
Run Code Online (Sandbox Code Playgroud)
代码在mingw32-g ++中成功编译.但在VS2008中失败了,错误是:
error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'iArray' : unknown size
Run Code Online (Sandbox Code Playgroud)
我认为枚举值是常量,因此它应该用作数组的长度.对?
我很困惑,你能帮助我吗?谢谢.
我已将问题减少到以下几点:
struct A {
static constexpr std::size_t f() { return 4; }
};
template<std::size_t N>
struct B : A {
alignas(A::f()) char a[N];
};
Run Code Online (Sandbox Code Playgroud)
我没有看到这有什么问题,但如果我尝试编译使用g++:
main.cpp:9:19: error: expression 'A::f' is not a constant-expression
alignas(A::f()) char a[N];
^
main.cpp:9: confused by earlier errors, bailing out
Run Code Online (Sandbox Code Playgroud)
再现可用上coliru.
constexpr int *np = nullptr和之间有什么区别int const *np = nullptr?
np在两种情况下,都是指向null的int的常量指针.constexpr在指针的上下文中是否有任何特定用法.
考虑以下功能:
template <size_t S1, size_t S2>
auto concatenate(std::array<uint8_t, S1> &data1, std::array<uint8_t, S2> &data2) {
std::array<uint8_t, data1.size() + data2.size()> result;
auto iter = std::copy(data1.begin(), data1.end(), result.begin());
std::copy(data2.begin(), data2.end(), iter);
return result;
}
int main()
{
std::array<uint8_t, 1> data1{ 0x00 };
std::array<uint8_t, 1> data2{ 0xFF };
auto result = concatenate(data1, data2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当使用clang 6.0编译时,使用-std = c ++ 17,此函数无法编译,因为数组上的size成员函数不是constexpr,因为它是一个引用.错误消息是这样的:
错误:非类型模板参数不是常量表达式
当参数不是引用时,代码按预期工作.
我想知道为什么会这样,因为size()实际上返回一个模板参数,它几乎不再是const.参数是否是参考不应该有所作为.
我知道我当然可以使用S1和S2模板参数,该功能仅仅是问题的简短说明.
标准中有什么吗?我很惊讶地发现了编译错误.