8

During some investigation related to "Variable template" I found out some strange code behaviour for me. Does standard say anything about this behaviour?

//Header.h
#pragma once

template<typename T>
auto myvar = []() -> T&{
    static T v;
    return v;
};

//Source.cpp
#include <iostream>
#include "Header.h"

void testFunction()
{
    std::cout << myvar<int>() << '\n';
}

//main.cpp
#include <iostream>
#include "Header.h"

void testFunction();

int main(int argc, char **argv) 
{
    myvar<int>() = 10;

    testFunction();

    std::cout << myvar<int>() << '\n';
}

Output:

0
10

I expect:

10
10
5
  • 4
    You have two different instantiations of the template, one in each translation unit. Each instance of the function will have its own static local variable. This is fine and expected. Commented Oct 3, 2018 at 14:40
  • 2
    @Someprogrammerdude: I would say ODR violation, so no valid expectation. Commented Oct 3, 2018 at 14:50
  • I'm not sure what you're setting out to prove here but I can't say I like this code. Commented Oct 3, 2018 at 14:55
  • 2
    @Someprogrammerdude aren't variable templates instantiations implicitly inline? Commented Oct 3, 2018 at 15:00
  • @Quentin Doesn't say on cppreference.com, but it might be in the specification. Commented Oct 3, 2018 at 15:09

1 Answer 1

1

Currently, you have ODR violation:

In both translation units, you have (after substitution)

auto myvar<int> = []() -> int&{
    static int v;
    return v;
};

but lambda declares a different type for each TU, so you have lambda1 and lambda2 for myvar<int>.

Each lambda has its own static, that is why you see that result in practice (but program is ill-formed anyway, NDR).

Sign up to request clarification or add additional context in comments.

1 Comment

It looks like a truth. I don't see any other explanation. (But if I declare any other type for example "int" it works as I expect. Note: in the last Vandevoorde's book "C++ Templates: The Complete Guide" he says that each instance of "Template variable" in the different translation unit has inline behaviour and value is shared). It seems that such behaviour only related to lambdas. Tnx

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.