Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8195569
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T05:10:53+00:00 2026-06-07T05:10:53+00:00

I know that the C++ standard says (sec 9.4.2 paragraph 4) that a static

  • 0

I know that the C++ standard says (sec 9.4.2 paragraph 4) that a static member variable of integral or enum type can provide an initializer inside the class, but that this requires a definition of that member outside the class (in a compilation unit). I.e., you need to do something like this:

class A
{
public:
    static const int X = 10;
};

// this is required by the standard
const int A::X;

I’ve seen (and I’ve seen it said other places) that some compilers will let you get away without the outside-of-class definition. This works on gcc 4.2.1 on OS X:

#include <iostream>    

class A
{
public:
    static const int X = 10;
};

int main(int argc, char** argv)
{
    std::cout << A::X << std::endl;
    return 0;
}

I recently encountered a bug where someone had done this, but they were using the member variable inside a templated function (std::max to be exact), and it would NOT compile, complaining about the undefined symbol A::X. I.e., this doesn’t work:

#include <iostream> 
#include <algorithm>   

class A
{
public:
    static const int X = 10;
};

int main(int argc, char** argv)
{
    std::cout << std::max(1, A::X) << std::endl;
    return 0;
}

Adding back in the outside-of-class definition makes it work.

This is sort of an academic question, but I’d like to know why this happens. Especially in relation to the fact that if we replace the static member variable with a static function (static const int X = 10; becomes static int X(), A::X becomes A::X()), then it will compile without the outside-of-class definition. The reason I mention templates is because std::max is templated, and other templated functions reproduce the same behavior. It may not be specifically related to templates, but I’d like to understand why it is that templates cause the behavior that they do. I assume this must have to do with the way that templates and static members get compiled/implemented?

PS – I posted some minimal code on github

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-07T05:10:54+00:00Added an answer on June 7, 2026 at 5:10 am

    It will compile without a definition.

    The definition is needed at link time, if the static member variable is odr-used. (It wouldn’t be odr-used if the compiler managed to substitute its actual value every time it was referenced. On the other hand, taking its address is sure to make it odr-used)

    This is the complete rule (section 9.4.2 [class.static.data]):

    If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used in the program and the namespace scope definition shall not contain an initializer.

    and from section 3.2 [basic.def.odr]:

    A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an
    object that satisfies the requirements for appearing in a constant expression and the lvalue-to-rvalue conversion is immediately applied.

    The requirements for appearing in a constant expression ARE satisfied, so everything depends on whether it is used as an lvalue or rvalue.

    std::max takes an lvalue reference, so there is not an immediate lvalue-to-rvalue conversion.


    The only interaction with templates is that there could be multiple equivalent definitions and the linker will pick any one. In your case, there is no template, so multiple definitions would produce a “symbol multiply defined” type of error.

    When you forget to provide a definition, both cases (member of template class and member of ordinary class) will give the same error: “undefined symbol”.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I know that the C++ standard says that return 0 is inserted at the
I know that in standard SQL you can do this: update top (100) table1
Can anyone confirm what the standard says about the default return type of vararg
So we know that the standard doesn't force pointer sizes to be equal. (
I know __proto__ is deprecated (or not part of the standard) and all that
The section §3.9.1/6 from the C++ Standard says, Values of type bool are either
I need to validate shipping container numbers. There is an industry standard that says
ISO C++ says that the inline definition of member function in C++ is the
I know that dip is standard for determining sizes on android. So when the
i know that there is some rules and standards in css handling but i

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.