Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Final binary size: constexpr variable vs constexpr function

Tags:

c++

constexpr

First, I have read this very informative answer about stylistic difference between defining a constexpr variable vs constexpr function. My question is more related with the final size of the binary when using these two. Consider this code:

// approach 1
template <typename T>
struct foo
{
  static constexpr char name[] = "mickey";
};

// approach 2
template <typename T>
struct bar
{
  static constexpr const char* getName() { return "mickey"; }
};

const char* func1() { return foo<int>::name; }
const char* func2() { return foo<double>::name; }

const char* func3() { return bar<int>::getName(); }
const char* func4() { return bar<double>::getName(); }

Look at this code in this godbolt link as well. While approach 1 returns different copies of name, approach 2 returns only one copy for all the different instantiations for different T. Infact, when I created 100 different types approach 2 led to a considerably smaller binary. Was wondering if anyone has experienced something similar.

like image 774
skgbanga Avatar asked Feb 11 '26 00:02

skgbanga


1 Answers

Well, those two approaches aren't really the same. There are things you can do with foo<T>::name that you cannot do with bar<T>::getName(): I can take a pointer to it and I can take a reference to it. That ability prevents different foo<T>::names from being the same.

But with getName(), there's no such issue. You just get a prvalue - you can't take its address. The different bar<T>::getName functions themselves have to be different, but not the underlying storage.

like image 193
Barry Avatar answered Feb 13 '26 07:02

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!