I want to be able to create structs with each having a member that indicates the struct's (not the object's) order. There should be no run-time overhead, and I should be able to use the ordinal at compile-time.
The simples approach doesn't work because for some reason static variables don't work at compile-time:
int nextOrdinal() {
static int ordinal;
return ordinal++;
}
struct S1 {
enum ordinal = nextOrdinal();
}
struct S2 {
enum ordinal = nextOrdinal();
}
How the structs are created isn't important to me at this moment. The problem seems to be that it's not possible to retain a state at compile-time, am I correct?
--Inspired by Boost.units dimensional analysis.
There are no variables at compile-time (excepting the very special case of inside of a CTFE function)--everything must be constant. Further, allowing CTFE variables to go static and pollute the interpreted environment would be a pretty iffy design choice.
Part of the problem is that the compiler doesn't make any guarantees (to my knowledge) about the order of compilation of various code units and may even (in the future) be able to compile pieces in parallel. In general you need to treat compile-time programming as a very strict functional environment with small pockets of flexible mutability (inside CTFE functions). To ensure consistency, CTFE-able functions must be pure and "Executed expressions may not reference any global or local static variables." http://dlang.org/function.html#interpretation
In short, I don't think there's any way to have the compiler store this state for you.
I don't know of a reliable way to do this, but if you want to order them based on their location in the source file you could do this:
import std.conv;
import std.stdio;
size_t nextOrdinal(size_t line = __LINE__)()
{
return line;
}
struct S1 {
enum ordinal = nextOrdinal();
}
struct S2 {
enum ordinal = nextOrdinal();
}
void main()
{
writeln(S1.ordinal);
writeln(S2.ordinal);
}
If you have multiple files that call nextOrdinal you could end up with struct definitions which have the same ordinal value. You might consider encoding the file name too:
size_t nextOrdinal(string file = __FILE__, size_t line = __LINE__)()
{
size_t res;
foreach (ch; file)
res += ch;
return res + line;
}
Related
I currently have a function which loads variables from a config file. It uses these to initialise a set of constant config variables.
// header file
namespace cfg {
extern const char *config_value;
}
// source file
namespace cfg {
const char *config_value;
}
bool load_config() {
cfg::config_value = load_config_line("config_value");
}
const char *load_config_line(const char *key) {
// read value from config.cfg...
}
This works pretty well. The problem is that now I want to reuse this code in several other projects, which means the constant values have to change. This means changing the config_value names in four different places each in the code. It also means I have several copies of essentially the same code to maintain in different projects.
Is there a way of setting different sets of constant values using the same code for the reading and parsing? Perhaps so that all I have to do is change the header file and it automatically finds those value names in the config file? The tricky part is that ideally the outward facing config values themselves should be constant and available at compile time (using a string to value map for example is undesirable, as I would prefer to have the compile time protection).
The solution here is to not use global variables, and instead have some settings struct which you explicitly initialize with values loaded from the file. The struct instance itself doesn't need to be const (you'll need to be able to load the values into it, unless you pass everything in on construction), but all access to it should be const. This last bit can be achieved by passing settings as e.g. a const settings& to wherever it is needed.
int main()
{
// Variant A: 2-step init
settings s;
s.loadConfigFile(filename);
// Variant B: 1-step init - can make instance itself const
const settings s(filename);
Thing worker(s); // Thing::Thing(const settings&)
worker.work();
}
Of course Worker can be anything your heart desires.
Note that settings itself needs no special constness whatsoever:
struct settings
{
std::string config_value;
}
It is the external const that guards access to the values contained within.
I have a function that performs a few string comparisons based on an argument. The strings that are being compared against are not used elsewhere. My instinct is to declare all of the strings as consts at the beginning of the function. However, they could just be inline, or declared on the class level. What is preferred?
Here is the gist of the function:
void MyType::parse(const wstring& input)
{
if (input == value1) { do1; }
else if (input == value2) { do2; }
}
Possible options for the values:
A. Inline values:
if (input == L"foo") { do1; }
B. Function-level values:
void MyType::parse(const wstring& input)
{
const wstring foo = L"foo";
if (input == foo) { do1; }
...
}
C. Class-level static constants:
.h
class MyType
{
private:
static const std::wstring kFoo;
}
.cpp
const wstring MyType::kFoo(L"foo");
...
void MyType::parse(const wstring& input)
{
if (input == kFoo) { do1; }
...
}
There are probably other options as well. Now, opinions differ as to readability, so while those are important, it's impossible to have a definite answer about that. So, when I ask, "which is preferred?" I'm asking about which performs best and has the lowest complexity.
My personal preference:
Keep the literal as close to the point of use as possible - so options A or B, but not C.
To choose between A an B, ask yourself "Does the literal itself make sense to someone else reading this code?". If it does, go for A and the code is still self-documenting. If it doesn't, option B gives you the opportunity to provide a meaningful name to the literal.
Examples:
// option A
void MyType::parse(const wstring& input)
{
if (input == L"QUIT") { quit(); }
else if (input == L"CONTINUE") { read_next(); }
}
// option B
void MyType::parse(const wstring& input)
{
static const wstring quit_command = L"*34!";
static const wstring continue_command = L"*17!";
if (input == quit_command) { quit(); }
else if (input == continue_command) { read_next(); }
}
What do you prefer?
They're not all equivalent of course.
If you give them (named) namespace or global scope, they can get external visibility, meaning you can define them in a separate TU and even change their definition without recompiling (just linking). If that TU is in a dynamic library that linking might be at runtime.
Also, function locals are usually not separately documented. However if these values have significant meaning, you might want to document them. If you don't wish to imply external linkage, make them file-static, e.g.:
namespace /*local to TU*/ {
/** #brief the file pattern is used when ...
*/
constexpr char const* file_pattern = "......";
}
That way, your class declaration doesn't leak implementation details and doesn't need to change if those details change.
So, it's up to you. But consider your needs for testing, maintainability and documentation.
The question you have to ask is: do you see this string being changed/modified in the future? If so, inline will not work. If you know this string will never be changed, received through a get() function, or modified, then I would say inline is best since you do not have to declare space in memory to hold the variable (and save a line of code).
I personally would go with the last variant. You have one single point of change if you require your "Magic String" to be modified, which is always a good idea. Even if you only use the string once, I would suggest that you still have one constant somewhere, otherwise you will do it the one way for this scenario, but the other way in another, which is inconsistent.
Just my 2 ct.
Generally, you should refer to your employer's coding standard.
If that does not explain which to use, ask your team lead.
If he/she does not care, your instincts are fine.
My experience has been varied ... I prefer the const std::string defined close to the first time used.
Edit: (some now missing comment apparently thought the above was incomplete)
Should single-use values be
inline function-level const variables,
class-level static const variables
As I previously stated;
I prefer the single-use value as close to the first time use as possible.
and thus not in the class-level constants (neither static nor otherwise)
I generally prefer them on their own line, so perhaps this means not in-line, and not anonymous. I suppose this is related to the idea of "no magic numbers in your code." (even though this is not a number.)
I have some small helper functions needed throughout the code.
To work, they need to be initialized with some data once.
Where should I store the init data?
I've come up with two methods:
I create static variables in the scope of the helper.cpp file which I set with a dedicated setter function and then use in my helper function.
static int _initData = 0;
void initHelpMe(int initData)
{
_initData = initData;
}
void helpMe()
{
doSomethingWith(_initData);
}
Or I use a static function variable inside the original helper function and a default parameter to it.
void helpMe(int initData = 0)
{
static int _initData = 0;
if (initData != 0)
_initData = initData;
doSomethingWith(_initData);
}
(Lets asume that 0 is outside of the valid data range of initData and that I've not shown additional code to ensure an error is raised when the function is called for the first time without initiating it first.)
What are the advantages / disadvantages of those two methods and is there an even better way of doing it?
I of course like the second method, because it keeps all the functionality in one place. But I already know it is not thread-safe (which is not an issue a.t.m.).
And, to make this more interesting, albeit being C++ this is not to be used in object-oriented but in procedural code. So please no answers proposing objects or classes. Just imagine it to be C with the syntax of C++.
I was going to suggest that you wrap your data into an object, until I realized that you are asking for a C solution with a C++ tag...
Both of your solutions have their benefits.
The second one is the one I'd prefer, assuming we just go by "what it looks like/maintainability". However, there is a drawback if helpMe is called MANY times with initData == 0, because of the extra if, which isn't present in the first case. This may or may not be an issue if doSomethingWith() is long enough a function and/or the compiler has the ability to inline helpMe (and initData is constant).
And of course, something in the code will have to call initHelpMe too, so it may turn out to be the same anyway.
In summary: Prefer the second one, based on isolation/encapsulation.
I clearly prefer the second! Global static data in different compilation units are initialized in unspecified order (In one unit in order, though). Local static data of a function is initialized at first call.
Example:
If you have two translation units A and B. The unit A calls during initialization the function helpMe of unit B. Assume the order of initialization is A, B.
The first solution will set the zero initialized _initData to some initData. After that the initialization of unit B resets _initData back to zero and may produce a memory leak or other harm.
There is a third solution:
void helpMe(int initData = 0)
{
static std::once_flag once;
static int _initData = 0;
std::call_once(once, [&] {
_initData = initData;
}
doSomethingWith(_initData);
}
I feel strongly both ways.
Prefer option 2 for the isolation, but option 1 lends itself to porting to a C++ class. I've coded both ways. It comes down to the SW architecture.
Let me offer another point.
Both options down side: You have not limited initialization to one occurrence. "need to be initialized with some data once". It appears OP's conditions insure a proper initialization of initHelpMe(123) or HelpMe(123) followed by helpMe(), but do not prevent/detect a secondary initialization.
Should a secondary need to be prevented/detected, some additional code could be used.
// Initialization
if (_initData != 0) {
; // Handle error
}
_initData = initData;
Another paradigm I've used follows. It may not be realizable in you code as it does not pass initData as a parameter but magically can get it.
void helpMe(void) {
static int Initialized = 0;
if (!Initialized) {
Initialized = 1;
_initData = initData();
}
doSomethingWith(_initData);
}
Suppose I have a class Utility in a file utility.h:
class Utility {
public:
static double longDescriptiveName(double x) { return x + 42; }
};
And then I find that I use the function longDescriptiveName(...) a LOT. So like an irresponsible C++ programmer that I am when I've had too much coffee, I create a new file utilitymacros.h and add the following there:
#define ldn Utility::longDescriptiveName
Now I include "utilitymacros.h" in any *.cpp where I use ldn(...) and my heart is filled with joy over how much more convinient it is to type 3 letters vs 28.
Question: Is there a safer (more proper) way of doing this than with #define?
I've noticed that I have to include "utilitymacros.h" after including boost headers, which I obviously don't like because it's a sign of clashes (though the Boost errors I get are not very clear as to what the clash is).
Clarification 1: On Code Readability
In case you might say that this negatively affects code readability, I assure you it does not, because it's a small set of functions that are used A LOT. An example that is widely know is stoi for stringToInteger. Another is pdf for probabilityDensityFunction, etc. So if I want to do the following, stoi is more readable in my opinion:
int x = stoi(a) + stoi(b) + stoi(c) + stoi(d);
Than:
int x = Utility::stringToInteger(a) + Utility::stringToInteger(b)
+ Utility::stringToInteger(c) + Utility::stringToInteger(d);
Or:
int x = Utility::stringToInteger(a);
x += Utility::stringToInteger(b);
x += Utility::stringToInteger(c);
x += Utility::stringToInteger(d);
Clarification 2: Editor Macro
I use Emacs as my IDE of choice and a Kinesis keyboard so you KNOW I use a ton of keyboard macros, custom keyboard shortcuts, as well as actually modifying what I see in the editor vs what's actually stored in the h/cpp file. But still, I feel like the simplicity and visual readability (as argued above) of using a function abbreviation in a few select cases really is the result I'm looking for (this is certainly subject to a degree).
Instead of macro, you could write inline function that forwards the call to the actual function:
inline double ldn(double x)
{
return Utility::longDescriptiveName(x);
}
That is certainly safer than macro.
You could use a function reference:
double (&ldn)(double) = Utility::longDescriptiveName;
How about configuring a snippit/macro/similar thing in your text editor? This way you only have to type ldn or something like that and the code doesn't have to run through the preprocessor risking difficult to find bugs later.
I don't know if this helps, but I think part of the problem may be the use of overly general namespaces (or class names, in this case), such as Utility.
If instead of Utility::stringToInteger, we had
namespace utility {
namespace type_conversion {
namespace string {
int to_int(const std::string &s);
}
}
}
Then the function could locally be used like this:
void local_function()
{
using namespace utility::type_conversion::string;
int sum = to_int(a) + to_int(b) + to_int(c) + to_int(d);
}
Analogously, if classes/structs and static functions are used (and there can be good reasons for this), we have something like
strut utility {
struct type_conversion {
struct string {
static int to_int(const std::string &s);
};
};
};
and the local function would look something like this:
void local_function()
{
typedef utility::type_conversion::string str;
int sum = str::to_int(a) + str::to_int(b)
+ str::to_int(c) + str::to_int(d);
}
I realize I am not telling you anything about syntax you didn't know already; it's more a reminder of the fact that the organization and structure of namespaces and classes itself plays an important role in making code more readable (and writable).
One alternative is to rename your function and put it in a namespace instead of a class, since it is static anyway. utility.h becomes
namespace Utility {
// long descriptive comment
inline double ldn(double x) { return x + 42; }
}
Then you can put using namespace Utility; in your client code.
I know there are lots of style guides out there saying short names are a bad thing, but I don't see the point of obeying some style and then circumventing it.
You can use alias template (since C++11).
using shortName = my::complicate::function::name;
I'm trying to initialize a global array of function pointers at compile-time, in either C or C++. Something like this:
module.h
typedef int16_t (*myfunc_t)(void);
extern myfunc_array[];
module.cpp
#include "module.h"
int16_t myfunc_1();
int16_t myfunc_2();
...
int16_t myfunc_N();
// the ordering of functions is not that important
myfunc_array[] = { myfunc_1, myfunc_2, ... , myfunc_N };
func1.cpp, func2.cpp, ... funcN.cpp (symbolic links to a single func.cpp file, so that different object files are created: func1.o, func2.o, func3.o, ... , funcN.o. NUMBER is defined using g++ -DNUMBER=N)
#include "module.h"
#define CONCAT2(x, y) x ## y
#define CONCAT(x, y) CONCAT2(x, y)
int16_t CONCAT(myfunc_, NUMBER)() { ... }
When compiled using g++ -DNUMBER=N, after preprocessing becomes:
func1.cpp
...
int16_t myfunc_1() { ... }
func2.cpp
...
int16_t myfunc_2() { ... }
and so on.
The declarations of myfunc_N() and the initialization of myfunc_array[] are not cool, since N changes often and could be between 10 to 200. I prefer not to use a script or Makefile to generate them either. The ordering of functions is not that important, i can work around that. Is there a neater/smarter way to do this?
How To Make a Low-Level Function Registry
First you create a macro to place pointers to your functions in a special section:
/* original typedef from question: */
typedef int16_t (*myfunc)(void);
#define myfunc_register(N) \
static myfunc registered_##myfunc_##N \
__attribute__((__section__(".myfunc_registry"))) = myfunc_##N
The static variable name is arbitrary (it will never be used) but it's nice to choose an expressive name. You use it by placing the registration just below your function:
myfunc_register(NUMBER);
Now when you compile your file (each time) it will have a pointer to your function in the section .myfunc_registry. This will all compile as-is but it won't do you any good without a linker script. Thanks to caf for pointing out the relatively new INSERT AFTER feature:
SECTIONS
{
.rel.rodata.myfunc_registry : {
PROVIDE(myfunc_registry_start = .);
*(.myfunc_registry)
PROVIDE(myfunc_registry_end = .);
}
}
INSERT AFTER .text;
The hardest part of this scheme is creating the entire linker script: You need to embed that snippet in the actual linker script for your host which is probably only available by building binutils by hand and examining the compile tree or via strings ld. It's a shame because I quite like linker script tricks.
Link with gcc -Wl,-Tlinkerscript.ld ... The -T option will enhance (rather than replace) the existing linker script.
Now the linker will gather all of your pointers with the section attribute together and helpfully provide a symbol pointing before and after your list:
extern myfunc myfunc_registry_start[], myfunc_registry_end[];
Now you can access your array:
/* this cannot be static because it is not know at compile time */
size_t myfunc_registry_size = (myfunc_registry_end - myfunc_registry_start);
int i;
for (i = 0; i < myfunc_registry_size); ++i)
(*myfunc_registry_start[i])();
They will not be in any particular order. You could number them by putting them in __section__(".myfunc_registry." #N) and then in the linker gathering *(.myfunc_registry.*), but the sorting would be lexographic instead of numeric.
I have tested this out with gcc 4.3.0 (although the gcc parts have been available for a long time) and ld 2.18.50 (you need a fairly recent ld for the INSERT AFTER magic).
This is very similar to the way the compiler and linker conspire to execute your global ctors, so it would be a whole lot easier to use a static C++ class constructor to register your functions and vastly more portable.
You can find examples of this in the Linux kernel, for example __initcall is very similar to this.
I was going to suggest this question is more about C, but on second thoughts, what you want is a global container of function pointers, and to register available functions into it. I believe this is called a Singleton (shudder).
You could make myfunc_array a vector, or wrap up a C equivalent, and provide a function to push myfuncs into it. Now finally, you can create a class (again you can do this in C), that takes a myfunc and pushes it into the global array. This will all occur immediately prior to main being called. Here are some code snippets to get you thinking:
// a header
extern vector<myfunc> myfunc_array;
struct _register_myfunc {
_register_myfunc(myfunc lolz0rs) {
myfunc_array.push_back(lolz0rs);
}
}
#define register_myfunc(lolz0rs) static _register_myfunc _unique_name(lolz0rs);
// a source
vector<myfunc> myfunc_array;
// another source
int16_t myfunc_1() { ... }
register_myfunc(myfunc_1);
// another source
int16_t myfunc_2() { ... }
register_myfunc(myfunc_2);
Keep in mind the following:
You can control the order the functions are registered by manipulating your link step.
The initialization of your translation unit-scoped variables occurs before main is called, i.e. the registering will be completed.
You can generate unique names using some macro magic and __COUNTER__. There may be other sneaky ways that I don't know about. See these useful questions:
Unnamed parameters in C
Unexpected predefined macro behaviour when pasting tokens
How to generate random variable names in C++ using macros?
Your solution sounds much too complicated and error prone to me.
You go over your project with a script (or probably make) to place the -D options to the compiler, anyhow. So I suppose you are keeping a list of all your functions (resp. the files defining them).
I'd use proper names for all the functions, nothing of your numbering scheme and then I would produce the file "module.cpp" with that script and initialize the table with the names.
For this you just have to keep a list of all your functions (and perhaps filenames) in one place. This could be easier be kept consistent than your actual scheme, I think.
Edit: Thinking of it even this might also be overengineering. If you have to maintain a list of your functions somewhere in any case, why not just inside the file "module.cpp"? Just include all the header files of all your functions, there, and list them in the initializer of the table.
Since you allow C++, the answer is obviously yes, with templates:
template<int N> int16_t myfunc() { /* N is a const int here */ }
myfunc_array[] = { myfunc<0>, myfunc<1>, myfunc<2> }
Now, you might wonder if you can create that variable-length initializer list with some macro. The answer is yes, but the macro's needed are ugly. So I'n not going to write them here, but point you to Boost::Preprocessor
However, do you really need such an array? Do you really need the name myfunc_array[0] for myfunc<0> ? Even if you need a runtime argument (myfunc_array[i]) there are other tricks:
inline template <int Nmax> int16_t myfunc_wrapper(int i) {
assert (i<Nmax);
return (i==Nmax) ? myfunc<Nmax> : myfunc_wrapper(i-1);
}
inline int16_t myfunc_wrapper(int i) {
return myfunc_wrapper<NUMBER>(i); // NUMBER is defined on with g++ -DNUMBER=N
}
Ok I worked out a solution based on Matt Joiner's tip:
module.h
typedef int16_t (*myfunc_t)(void);
extern myfunc_array[];
class FunctionRegistrar {
public:
FunctionRegistrar(myfunc_t fn, int fn_number) {
myfunc_array[fn_number - 1] = fn; // ensures correct ordering of functions (not that important though)
}
}
module.cpp
#include "module.h"
myfunc_array[100]; // The size needs to be #defined by the compiler, probably
func1.cpp, func2.cpp, ... funcN.cpp
#include "module.h"
static int16_t myfunc(void) { ... }
static FunctionRegistrar functionRegistrar(myfunc, NUMBER);
Thanks everyone!