I want to use a simple compile time constant for example like this:
double foo(double x) { return x + kConstDouble; }
Now I see at least the following ways to define that constant
namespace { static constexpr double kConstDouble = 5.0; }
namespace { constexpr double kConstDouble = 5.0; }
static constexpr double kConstDouble = 5.0;
constexpr double kConstDouble = 5.0;
Which is the right way to go? Is there a difference when kConstDouble is defined in a header vs a source file?
Using static or an anonymous namespace will cause the variable to have internal linkage; it will only be visible within the same translation unit. So if you use one of these within a .cpp file, you won't be able to use the variable anywhere else. This would be done typically if the constant is an implementation detail of that unit of code. If you want to expose it to other translation units, you'll need to put it in a header file. The typical way to do that would be to declare it static (or put it in anonymous namespace), since it is a trivial and constant variable. The other approach would be to declare it extern in the header, and define it in the .cpp to get a truly global variable (as opposed top one where actually every tu has its own copy).
Between static and anonymous namespace; well you don't need both first of all. They both do the same thing AFAIK. But I think it is more idiomatic at this point to use anonymous namespaces in cpp files, as they can be used to also give functions, classes, etc internal linkage. On the other hand, when you want to use it for making a variable globally available, it's more common to use static; I never use anonymous namespaces in header files as I find it misleading.
Related
Consider a library that defines in a header file
struct Proj {
struct Depth {
static constexpr unsigned Width = 10u;
static constexpr unsigned Height = 10u;
};
struct Video {
static constexpr unsigned Width = 10u;
static constexpr unsigned Height = 10u;
};
};
The library gets compiled, and I'm now developing an application that links against this library. I thought for a long time it was some kind of visibility problem, but even after adding B_EXPORT (standard visibility stuff from CMake) everywhere with no change, I finally found the problem.
template <class Projection>
struct SomeApplication {
SomeApplication() {
unsigned height = std::max(// or std::max<unsigned>
Projection::Depth::Height,
Projection::Video::Height
);
}
};
I can't even reproduce the problem with a small dummy library / sample application. But using std::max in the application causes the link error, whereas if I just do it myself
unsigned height = Projection::Depth::Height;
if (height < Projection::Video::Height)
height = Projection::Video::Height;
Everything works out. AKA there don't appear to be any specific issues with the visibility in terms of just using Projection::XXX.
Any thoughts on what could possibly cause this? This is on OSX, so this doesn't even apply.
The problem is that Width and Height are declared, not defined in your structs. Effectively, this means there is no storage allocated for them.
Now recall the signature for std::max:
template<typename T>
const T& max(const T&, const T&);
Note the references: this means the addresses of the arguments are to be taken. But, since Width and Height are only declared, they don't have any storage! Hence the linker error.
Now let's consider the rest of your question.
Your hand-written max works because you never take any pointers or references to the variables.
You might be unable to reproduce this on a toy example because, depending on the optimization level in particular, a sufficiently smart compiler might evaluate max at compile time and save the trouble of taking the addresses at runtime. For instance, compare the disasm for no optimization vs -O2 for gcc 7.2: the evaluation is indeed done at compile-time!
As for the fix, it depends. You have several options, to name a few:
Use constexpr getter functions instead of variables. In this case the values they return will behave more like temporary objects, allowing the addresses to be taken (and the compiler will surely optimize that away). This is the approach I'd suggest in general.
Use namespaces instead of structs. In this case the variables will also be defined in addition to being declared. The caveat is that you might get duplicate symbol errors if they are used in more than one translation unit. The fix for that is only in form of C++17 inline variables.
...speaking of which, C++17 also changes the rules for constexpr static member variables (they become inline by default), so you won't get this error if you just switch to this standard.
In C++11, std::enable_if was added to the Standard Library. It is equivalent to boost::enable_if_c whose condition is a bool. This is suitable for rather simple conditions, but as soon as you use predicates that hold their result in a value constant, you have to use the more verbose construct my_predicate<MyArgs>::value to turn it into bool.
This is exactly what boost::enable_if (without _c suffix) was made for.
Why is there no equivalent in Standard Library?
The standard library goes a different route here. C++17 added variable templates shortcuts for all the type traits that return a ::value. The pattern is always
template <typename... Args>
some_trait_v = some_trait<Args...>::value;
For instance you can write
std::enable_if<std::is_same_v<T1,T2>>
Further the argument for enable_if could be the result of constexpr expressions, for instance
std::enable_if<some_constexpr_function<T1,T2>()>
This way is more generic and does not depend on passing something that must have a value member.
Declaring const global variables has proven useful to determine some functioning parameters of an API. For example, on my API, the minimum order of numerical accuracy operators have is 2; thus, I declare:
const int kDefaultOrderAccuracy{2};
as a global variable. Would it be better to make this a static const public data member of the classes describing these operators? When, in general, is better to choose one over the other?
const int kDefaultOrderAccuracy{2};
is the declaration of a static variable: kDefaultOrderAccuracy has internal linkage. Putting names with internal linkage in a header is obviously an extremely bad idea, making it extremely easy to violate the One Definition Rule (ODR) in other code with external linkage in the same or other header, notably when the name is used in the body of an inline or template function:
Inside f.hpp:
template <typename T>
const T& max(const T &x, const T &y) {
return x>y ? x : y;
}
inline int f(int x) {
return max(kDefaultOrderAccuracy, x); // which kDefaultOrderAccuracy?
}
As soon as you include f.hpp in two TU (Translation Units), you violate the ODR, as the definition is not unique, as it uses a namespace static variable: which kDefaultOrderAccuracy object the definition designates depends on the TU in which it is compiled.
A static member of a class has external linkage:
struct constants {
static const int kDefaultOrderAccuracy{2};
};
inline int f(int x) {
return max(constants::kDefaultOrderAccuracy, x); // OK
}
There is only one constants::kDefaultOrderAccuracy in the program.
You can also use namespace level global constant objects:
extern const int kDefaultOrderAccuracy;
Context is always important.
To answer questions like this.
Also for naming itself.
If you as a reader (co-coder) need to guess what an identifier means, you start looking for more context, this may be supported through an API doc, often included in decent IDEs. But if you didn't provide a really great API doc (I read this from your question), the only context you get is by looking where your declaration is placed.
Here you may be interested in the name(s) of the containing library, subdirectory, file, namespace, or class, and last not least in the type being used.
If I read kDefaultOrderAccuracy, I see a lot of context encoded (Default, Order, Accuracy), where Order could be related for sales or sorting, and the k encoding doesn't say anything to me. Just to make you looking on your actual problem from a different perspective. C/C++ Identifiers have a poor grammar: they are restricted to rules for compound words.
This limitation of global identifiers is the most important reason why I mostly avoid global variables, even constants, sometimes even types. If its the meaning is limited to a given context, define a thing right within this context. Sometimes you first have to create this context.
Your explanation contains some unused context:
numerical operators
minimum precision (BTW: minimum doesn't mean default)
The problem of placing a definition into the right class is not very different from the problem to find the right place for a global: you have to find/create the right header file (and/or namespace).
As a side note, you may be interested to learn that also enum can be used to get cheap compile-time constants, and enums can also be placed into classes (or namespaces). Also a scoped enumeration is an option you should consider before introducing global constants. As with enclosing class definitions, the :: is a means of punctuation which separates more than _ or an in-word caseChange.
Addendum:
If you are interested in providing a useful default behaviour of your operations that can be overridden by your users, default arguments could be an option. If your API provides operators, you should study how the input/output manipulators for the standard I/O streams work.
my guess is that:
const takes up inline memory based on size of data value such as “mov ah, const value” for each use, which can be a really short command, in size overall, overall, based on input value.
whereas static values takes up a whole full data type, usually int, whatever that maybe on the current system for each static, maybe more, plus it may need a full memory access value to access the data, such as mov ah, [memory pointer], which is usually size of int on the system, for each use (with a full class it could even more complex). yet the static is still declared const so it may behave the same as the normal const type.
I have a lengthy numeric integration scheme written in C. I'd like to test my algorithm in floating point precision. Is there a way to tell gcc to demote every occurrence of double to float in the entire program?
You can't safely do this without modifying your source code, but that shouldn't be terribly difficult to do.
Using the preprocessor to force the keyword double in your program to be treated as float is a bad idea; it will make your program difficult to read, and if you happen to use long double anywhere it would be treated as long float, which is a syntax error.
As stix's answer suggests, you can add a typedef, either at the top of your program (if it's a single source file) or in some header that's #includeed by all the relevant source files:
typedef double real; /* or pick a different name */
Then go through your source code and change each occurrence of double to real. (Be careful about doing a blind global search-and-replace.)
Make sure that the program still compiles, runs, and behaves the same way after this change. Then you can change the typedef to:
typedef float real;
and recompile to use float rather than double.
It's not quite that simple, though. If you're using functions declared in <math.h>, you'll want to use the right function for whatever floating-point type you're using; for example, sqrt() is for double, sqrtf() is for float, and sqrtl() is for long double.
If your compiler supports it, you might use the <tgmath.h> header, which defines type-generic macros corresponding to the math functions from <math.h>. If you use <tgmath.h>, then sqrt(x) will resolve to call the correct square root function depending on the type of the argument.
typedef double float;
Before any doubles that you want to replace should work, however be warned it may confuse some external libraries.
In the future, the best approach is to define your own float type:
#ifdef USE_FLOATS
typedef float MyFloatType;
#else
typedef double MyFloatType;
#endif
Or use templates, which has the added benefit of allowing you to change the code at runtime to use one or the other.
I've learned that the C++11 standard doesn't allow friend functions to have default arguments unless the friend declaration is a definition. So this isn't allowed:
class bar
{
friend int foo(int seed = 0);
};
inline int foo(int seed) { return seed; }
but this is:
class bar
{
friend int foo(int seed = 0)
{
return seed;
}
};
(Example courtesy http://clang-developers.42468.n3.nabble.com/Clang-compile-error-td4033809.html)
What is the rational behind this decision? Friend functions with default arguments are useful, e.g. if the function is too complex to declare in place, why are they now disallowed?
In looking at DR 136, it looks like there are issues when a friend declaration combines with namespace-level declarations with default arguments that makes the semantics hard to reason about (and perhaps difficult to issue quality diagnostics against), especially in the context of templates. The proposed DR resolution given on that page is to only allow default arguments in them when the declaration is the only one in the program. Since a function definition is also a declaration, that would mean the only useful way to specify default arguments in a friend declaration is to make it a definition. I would guess the C++11 standard simply chose to make this practical usage requirement explicit.
(Technically, if by "program" they mean "translation unit", one could construct a complete program where the function were defined in a completely different translation unit, but since this function's definition would not have the class definition visible, the benefits of the friendship grant would be largely useless.)
The workaround for this hiccup seems pretty straightforward. Declare the friend without using default arguments, and then declare it again at namespace scope with whatever default arguments are desired.