标签: constant-expression

如何在TVarRec中设置字符串(或AnsiString)常量?

我想将格式化参数传递ArgsFormat函数.我找到了一些例子,但是我无法找到如何在TVarRec成员中分配字符串常量.以下代码在编译时失败E2089 Invalid typecast.

procedure TForm1.Button1Click(Sender: TObject);
var Arguments: array of TVarRec;
begin
  SetLength(Arguments, 2);

  Arguments[0].VInteger := 111;
  Arguments[1].VAnsiString :=  PAnsiString('Text'); // I want to set this member

  ShowMessage(Format('Decimal: %d, String: %s', Arguments));
end;
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议我如何将字符串(或AnsiString)常量设置为TVarRec成员?我正在使用Delphi 2009.

非常感谢

delphi string constant-expression open-array-parameters

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

为什么"初始化元素不是常数"是......不再工作了?

static const int a = 42;
static const int b = a;
Run Code Online (Sandbox Code Playgroud)

我希望在这样的代码中出现编译错误.初始值设定项必须是常量表达式或字符串文字.存储在int具有const类型限定符类型的对象中的值不是常量表达式.

我编译-Wall -Wextra -pedantic,甚至与-ansi.然后:

令人惊讶的是,以下内容:

static const char * const a = "a";
static const char * const b = a;
Run Code Online (Sandbox Code Playgroud)

c gcc language-lawyer constant-expression

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

[expr.const] 部分中“前面的初始化”一词的含义是什么

constexpr int func(int const& rf){
    return rf;
}
int main(){
   constexpr int value = func(0);
}
Run Code Online (Sandbox Code Playgroud)

考虑上面的代码,变量value应该由一个常量表达式初始化,即func(0),它首先应该是一个核心常量表达式。为了判断表达式是否func(0)是核心常量表达式,将应用以下规则,即:
expr.const#2.7

表达式 e 是核心常量表达式,除非对 e 的求值遵循抽象机的规则,将求值以下表达式之一:

左值到右值的转换,除非它应用于

[...], 或者

(2.7.4) 文字类型的非易失性泛左值,指的是其生命周期开始于 e 求值期间的非易失性对象;

尽管lvalue-to-rvalue conversion应用了rf并且这种转换满足了要点(2.7.4),但是,请看一下下一段,即:
expr.const#2.11

引用引用类型的变量或数据成员的 id 表达式,除非引用具有前面的初始化并且

  • (2.11.1) 它用常量表达式初始化,或者,
  • (2.11.2) 其生命周期开始于 e 的评估内;

我不知道这句话的真正preceding initialization含义是什么?这是否意味着变量应该在使用之前进行初始化,或者意味着在变量的声明中应该有一个初始值设定项。无论如何,在将 应用于lvalue-to-rvalue conversion glvalue之前rf,应该评估 glvaluerf以确定对象的身份,该身份由以下规则决定:

左值是一个表达式,其计算确定对象、位域或函数的标识。

这意味着不仅应遵守项目符号 [expr.const#2.7],还应遵守 [expr.const#2.11]。

因为 id-expressionrf是引用类型。因此,为了使表达式func(0)成为核心常量表达式,id-表达式rf必须有一个前置的初始化 …

c++ language-lawyer constant-expression c++17

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

“constexpr”函数中对“文字类型”的要求

这是我的代码:

class agg_t1{
    int x;      // private non-static data menber
};
class agg_t2{
    agg_t2(){}      // user-provided constructor
};
constexpr void ce1(agg_t1 arg){};       // OK
constexpr void ce2(agg_t2 arg){};       // ERROR:  parameter type 'agg_t2' is not a literal type 
Run Code Online (Sandbox Code Playgroud)

根据dcl.constexpr

constexpr 函数的定义应满足以下要求: ...

  • 它的每个参数类型都应该是文字类型;...

basic#types.general-10

如果类型是文字类型,则它是: ...

  • 它可以是闭包类型、聚合类型,或者......

我理解为什么agg_t2不是文字类型的原因是,它违反了规则dcl.init.aggr#1.1

聚合是一个数组或一个类......

  • 没有用户声明或继承的构造函数...

我认为agg_t1可能不是文字类型,因为它也违反了规则dcl.init.aggr#1.1

聚合是一个数组或一个类......

  • 没有私有或受保护的直接非静态数据成员...

然而......编译器结果告诉我我对 的假设是错误的agg_t1

我的问题是:

如果agg_t1的私有数据成员x …

c++ language-lawyer constant-expression constexpr constexpr-function

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

用户定义的文字在 C++20 中是否应该始终保持保守?

如果我没记错的话,用户定义的文字的参数在编译时总是已知的。在 C++20 中,您可以使用强制函数在编译时执行,consteval从而throw生成编译时错误。

\n
#include <limits>\n\nconsteval int operator""_int(unsigned long long int v) {\n    if (std::numeric_limits<int>::max() < v) {\n        throw "out of range";\n    }\n    return static_cast<int>(v);\n}\n\nint main() {\n    return 1\'000\'000\'000\'000_int;\n}\n
Run Code Online (Sandbox Code Playgroud)\n
$ g++ -std=c++20 main.cpp\nmain.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\nmain.cpp:11:12:   in \xe2\x80\x98constexpr\xe2\x80\x99 expansion of \xe2\x80\x98operator""_int(1000000000000)\xe2\x80\x99\nmain.cpp:5:9: error: expression \xe2\x80\x98<throw-expression>\xe2\x80\x99 is not a constant expression\n    5 |         throw "out of range";\n      |         ^~~~~~~~~~~~~~~~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n

根据我的经验,编译时错误通常比运行时错误更可取。

\n

如果必须在定义中调用其他不是 的函数constexpr,那么consteval显然不是一个选项。但除了这个例子,我想不出有什么理由不使用consteval.

\n

还有其他原因不将用户定义的文字标记为 吗consteval …

c++ constant-expression user-defined-literals c++20 consteval

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

常量变量与常量参考

在一些C++源代码中,我看到表达式结果可以保存为常量崇敬.像这样:

 const int &x = y + 1;
Run Code Online (Sandbox Code Playgroud)

这是什么意思?有没有这方面的文件?我找不到..


对我来说,它似乎相当于:

 const int x = y + 1;
Run Code Online (Sandbox Code Playgroud)

因为程序的结果保持不变.它真的相同吗?

如果是,为什么语言允许第一种方式来编写它?看起来很混乱.

如果没有什么区别?

c++ reference constant-expression

4
推荐指数
1
解决办法
272
查看次数

无法在F#中创建列表文字

我有以下几种类型

type StatusCode = 
    | OK          = 200
    | NoContent   = 204
    | MovedTemp   = 301
    | MovedPerm   = 302
    | SeeOther    = 303
    | NotModified = 304
    | NotFound    = 404
    | ServerError = 500

[<Literal>]
let NoBodyAllowedStatusCodes = [StatusCode.NoContent; StatusCode.NotModified]
Run Code Online (Sandbox Code Playgroud)

我得到一个编译时错误,说:

这不是有效的常量表达式或自定义属性值

我无法弄清楚这里有什么问题.

f# compile-time-constant constant-expression

4
推荐指数
1
解决办法
439
查看次数

为什么我不能把这个字符串变成Literal?

我需要将字符串转换为Literal,以便将其作为参数传递给CsvProvider.但我无法做到.下面的代码运行没有问题:

open System.IO
open FSharp.Data
open FSharp.Data.JsonExtensions

let charSwitch (a: char) b x =
    if x = a then
        b
    else
        x

let jsonDataPath = Path.Combine(__SOURCE_DIRECTORY__, @"data\fractal.json")
let jsonData = JsonValue.Load(jsonDataPath)

/// Path with traded assets
let trp = ((jsonData?paths?tradedAssets).AsString() |> Core.String.map (charSwitch '\\' '/')).ToString()
printfn "trp is a standard string: %s" trp
// trp is a standard string: H:/Dropbox/Excel/Data/Fractal/Traded.csv
Run Code Online (Sandbox Code Playgroud)

但是,添加以下两行时

[<Literal>]
let tradedPath = trp
Run Code Online (Sandbox Code Playgroud)

最后我得到了消息This is not a valid constant expression or custom attribute value.

我甚至试图复制trp,但这没有帮助. …

f# constant-expression

4
推荐指数
2
解决办法
284
查看次数

为什么C中的静态初始化表达式不能使用常量数组的元素?

以下(公认的做作)C程序无法编译:

int main() {
const int array[] = {1,2,3};
static int x = array[1];
}
Run Code Online (Sandbox Code Playgroud)

使用gcc(或Microsoft的CL.EXE)编译上述C源文件时,出现以下错误:

error: initializer element is not constant
static int x = array[1];
               ^
Run Code Online (Sandbox Code Playgroud)

这种简单直观的语法肯定是有用的,所以这似乎应该是合法的,但显然它不是.当然,我不是唯一一个对这种明显愚蠢的限制感到沮丧的人.我不明白为什么这是不允许的 - 通过使这个有用的语法非法,C语言试图避免什么问题?

看起来它可能与编译器为初始化生成汇编代码的方式有关,因为如果删除"static"关键字(使得变量"x"在堆栈上),那么它编译得很好.

然而,另一个奇怪的事情是它在C++中编译得很好(即使使用static关键字),但在C中却没有.因此,C++编译器似乎能够生成必要的汇编代码来执行这样的初始化.

编辑:相信戴维斯 - 为了安抚SO权力 - 我会寻求以下类型的事实信息来回答这个问题:

  1. 是否有支持这些语义的遗留代码会破坏?

  2. 这些语义是否已经正式提交给标准委员会?

  3. 有没有人有理由拒绝这些语义的允许?

c arrays initialization constant-expression

4
推荐指数
1
解决办法
215
查看次数

如何在常量计算表达式中获得编译时错误?

我有一个Assert用于评估断言的函数:

  • 如果前提条件在运行时失败,该函数将输出一条错误消息并终止程序。

  • 如果常量表达式中的前提条件失败,则会导致编译时错误。

我希望当断言在常量计算表达式中失败时,该函数也会生成编译时错误:

const int a = (Assert(false),0); //generate a runtime error 
                                 //=> I would like it generates a compile time error
Run Code Online (Sandbox Code Playgroud)

我考虑过使用std::is_constant_evaluatedcompiler-explorer

#include <type_traits>

using namespace std;

void runtime_error();

constexpr void compile_time_error(){} //should generates a compile time error

constexpr void Assert(bool value){
   if (value) return;
   if (is_constant_evaluated())
     compile_time_error();
   else
     runtime_error();
   }

void func(){
    const int a = (Assert(false),0);
    }
Run Code Online (Sandbox Code Playgroud)

我只使用 GCC,我寻找了一个会导致编译时错误的内置函数,该函数是 constexpr,但没有找到。

是否有任何技巧可以在可以常量求值的表达式中获得编译时错误?

c++ gcc assertion constant-expression c++20

4
推荐指数
1
解决办法
842
查看次数