简体   繁体   English

编译时常量索引是编译时常量数组本身的编译时常量吗?

[英]Is a compiletime constant index into a compiletime constant array itself compiletime constant?

I am trying to play fancy games which have the C++ compiler synthesize hash values of constant strings at compiletime.我正在尝试玩一些花哨的游戏,这些游戏让 C++ 编译器在编译时合成常量字符串的哈希值。 This would let me replace the string with a single identifier, with a massive savings in code size and complexity.这将让我用单个标识符替换字符串,大大节省代码大小和复杂性。

For programming clarity and ease, it'd be awesome if I could examine and compute at compiletime with simple inline character strings like "Hello" which are compiletime constant pointers to compiletime constant chars.为了编程的清晰度和易用性,如果我能在编译时使用简单的内联字符串(如“Hello”)进行检查和计算,那就太棒了,这些字符串是编译时常量字符的编译时常量指针。

If I can index into these at compiletime, I can make a template metaprogram to do what I want.如果我可以在编译时索引这些,我就可以制作一个模板元程序来做我想做的事。 But it is unclear if the C++ standard treats a ct-constant index of a ct-constant array as ct-constant by itself.但不清楚 C++ 标准是否将 ct-constant 数组的 ct-constant 索引本身视为 ct-constant。

Asked another way,换个方式问,

 const char v="Hello"[0];

is quite valid C++ (and C).是非常有效的 C++(和 C)。 But is the value va compile time constant?但是va 值是编译时间常数吗?

I already believe the answer is no, but in practice some compilers accept it without even any warning, much less error.我已经相信答案是否定的,但实际上一些编译器在没有任何警告的情况下接受了它,更不用说错误了。 For example, the following compiles and runs without even a single warning from Intel's C++ compiler:例如,以下编译和运行甚至没有来自英特尔 C++ 编译器的任何警告:

#include <iostream>
const char value="Hello"[0];
template<char c>  void printMe()
{
  std::cout << "Template Val=" << c << std::endl;
}

int main()
{
  const char v='H';
  printMe<'H'>();
  printMe<v>();
  printMe<value>(); // The tricky and interesting case!
}

However, Microsoft's compiler will not compile at all, giving a reasonably coherent error message about using a template with an object with internal linkage.但是,Microsoft 的编译器根本不会编译,给出了关于将模板与具有内部链接的对象一起使用的合理连贯的错误消息。

I suspect the answer to my question is "No, you can't assume any array reference even to a constant array with a constant index is constant at compiletime".我怀疑我的问题的答案是“不,即使对具有常量索引的常量数组,您也不能假设任何数组引用在编译时都是常量”。 Does this mean the Intel compiler's successful execution is a bug in the Intel compiler?这是否意味着英特尔编译器的成功执行是英特尔编译器中的一个错误?

It doesn't work on GCC either.它也不适用于 GCC。

However , outside of a language-compliance viewpoint, it's nice that the compiler optimiser does treat it as a character constant, pretty much.然而,在语言合规性观点之外,编译器优化器确实将其视为字符常量,这很好。 I exploited that fact to allow preprocessor-generated character constants (by using *#foo ).我利用这个事实来允许预处理器生成的字符常量(通过使用*#foo )。 See http://cvs.openbsd.org/cgi-bin/query-pr-wrapper?full=yes&numbers=1652 , in file hdr.h .请参阅文件hdr.h http://cvs.openbsd.org/cgi-bin/query-pr-wrapper?full=yes&numbers=1652 With that macro, you could write用那个宏,你可以写

DECR(h, e, l, l, o)

rather than而不是

DECR('h', 'e', 'l', 'l', 'o')

Much more readable, in my view.在我看来,更具可读性。 :-) :-)

Good question, yes this can be done, and its fine with the standards, and it'll work on Microsoft, GCC, and Intel, problem is you have the syntax wrong :)好问题,是的,这是可以做到的,并且符合标准,并且可以在 Microsoft、GCC 和 Intel 上运行,问题是您的语法有误:)

One second I'll cook up a sample... Ok done, here it is.等一下,我会做一个样品……好的,就在这里。 This sample is valid C++, and I've used it quite often, but indeed most programmers don't know how to get it right.这个示例是有效的 C++,我经常使用它,但确实大多数程序员不知道如何正确使用它。

template<char* MSG>
class PrintMe
{
public:
    void operator()()
    {
        printf(MSG);
    }
};

char    MyMessage[6] = "Hello"; //you can't use a char*, but a char array is statically safe and determined at compiletime

int main(int argc, char* argv[])
{
    PrintMe<MyMessage> printer;
    printer();
    return 0;
}

The relevant difference here is the difference between a "Integral Constant Expression" and a mere compile-time constant.这里的相关区别是“积分常量表达式”和单纯的编译时常量之间的区别。 "3.0" is a compile-time constant. “3.0”是编译时常量。 "int(3.0)" is a compile-time constant, too. “int(3.0)”也是一个编译时常量。 But only "3" is an ICE.但只有“3”是 ICE。 [See 5.19] [见5.19]

More details at boost.org 更多详情请访问 boost.org

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM