C++ 是否合法?将没有定义的 static const int 的地址传递给模板?

发布于 2024-08-02 07:22:42 字数 795 浏览 6 评论 0原文

我无法确定该代码是否应该编译,或者我尝试的两个编译器是否都有错误(GCC 4.2 和 Sun Studio 12)。一般来说,如果您在头文件中声明了静态类成员,则需要在某个源文件中定义它。然而,静态常量积分的标准有一个例外。例如,这是允许的:

#include <iostream>

struct A {
    static const int x = 42;
};

无需在类主体之外的某处添加 x 的定义。我正在尝试做同样的事情,但我也获取 x 的地址并将其传递给模板。这会导致链接器错误,抱怨缺乏定义。下面的示例不会链接(缺少 A::x 的定义),即使它全部位于同一个源文件中:

#include <iostream>

template<const int* y>
struct B {
    static void foo() { std::cout << "y: " << y << std::endl; }
};

struct A {
    static const int x = 42;
    typedef B<&x> fooness;
};

int main()
{
    std::cout << A::x << std::endl;
    A::fooness::foo();
}

这很奇怪,因为只要我不将地址传递给模板,它就可以工作。这是一个错误还是在某种程度上符合技术标准?

编辑:我应该指出 &A::x 不是运行时值。在编译时为静态分配的变量留出内存。

I'm having trouble deciding whether not this code should compile or if just both compilers I tried have a bug (GCC 4.2 and Sun Studio 12). In general, if you have a static class member you declare in a header file you are required to define it in some source file. However, an exception is made in the standard for static const integrals. For example, this is allowed:

#include <iostream>

struct A {
    static const int x = 42;
};

With no need to add a definition of x outside the class body somewhere. I'm trying to do the same thing, but I also take the address of x and pass it to a template. This results in a linker error complaining about a lack of definition. The below example doesn't link (missing a definition for A::x) even when it's all in the same source file:

#include <iostream>

template<const int* y>
struct B {
    static void foo() { std::cout << "y: " << y << std::endl; }
};

struct A {
    static const int x = 42;
    typedef B<&x> fooness;
};

int main()
{
    std::cout << A::x << std::endl;
    A::fooness::foo();
}

Which is bizarre since it works as long as I don't pass the address to a template. Is this a bug or somehow technically standards compliant?

Edit: I should point out that &A::x is not a runtime value. Memory is set aside for statically allocated variables at compile time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

御弟哥哥 2024-08-09 07:22:42

要成为一个结构良好的程序,如果实际使用静态变量,您仍然必须定义静态变量(在本例中没有初始化程序),并将地址计数作为使用:

  • C++2003 标准:9.4.2 静态数据成员第 4 段(加粗)

如果静态数据成员是 const
整型或常量枚举类型,
它在类中的声明
定义可以指定一个
常量初始化器应为
积分常量表达式 (5.19)。
在这种情况下,该成员可以出现在
积分常量表达式。
成员仍应定义在
命名空间范围,如果它被用在
程序和命名空间范围
定义不应包含
初始化器

To be a well formed program you stil have to have the defintion of the static variable (without an initializer in this case) if it actually gets used, and taking the address counts as a use:

  • C++2003 Standard: 9.4.2 Static data members Paragraph 4 (bold added)

If a static data member is of const
integral or const enumeration type,
its declaration in the class
definition can specify a
constant-initializer which shall be an
integral constant expression (5.19).
In that case, the member can appear in
integral constant expressions. The
member shall still be defined in a
namespace scope if it is used in the
program and the namespace scope
definition shall not contain an
initializer

从此见与不见 2024-08-09 07:22:42

您试图将运行时值传递给模板,这是不可能的。唯一允许的模板参数是类型(class/typename)或整型常量值(int/bool/etc)。

You are trying to pass a runtime value to a template, that's not possible. The only allowed template parameters are types (class/typename) or integral constant values (int/bool/etc).

只是在用心讲痛 2024-08-09 07:22:42

有趣的是,它在 VS 2008 上对我来说编译得很好。我有点假设错误来自 typedef,因为在编译时,当它尝试使用 &x 作为模板类型编译 'B' 时,它不知道在哪里x 的地址将是。尽管如此......它编译并给出了合理的输出。

Interesting, it compiled fine for me on VS 2008. I kind of assumed that the error came from the typedef because at compile time when it tries to compile 'B' with &x as the template type it doesn't then know where the address of x will be. Still... it compiles and gives a reasonable output.

兔姬 2024-08-09 07:22:42

无论如何,我可以看到人们可能期望它如何编译。

静态常量的地址实际上并不是运行时值,可以在链接时完全解析。

I could see how one might expect this to compile anyway.

The address of a static const isn't really a runtime value and can be fully resolved at link time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文