I am trying to convert an old Fortran 77 code to C++ and most of the variables are declared in Common blocks such as:
COMMON/BLK1/Gw(200),Eta(4096),t(4096),Phi(200),w(200)
COMMON/BLK2/g,dw,Vel,M,dt,N,Ioutp1,Ioutp2
COMMON/BLK3/Hs,Std,E,Hs1,Tdt
As I understand it, common blocks are used simply to make variables accessible throughout the program in different subroutines. Therefore, in a C++ program, would I be able to create structs with the variables (outside of the main) and call the variables this way as members of the struct?
Based on my understanding of COMMON from this page, the C++ equivalent would be to make a file called common.h (with include guards) that contains:
namespace BLK1
{
int const Gw = 200;
int const Eta = 4096;
int const t = 4096;
int const Phi = 200;
int const w = 200;
}
namespace BLK2
{
extern int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
extern int Hs, Std, E, Hs1, Tdt;
}
Also, in exactly one .cpp file in your project you need to provide a definition for any non-consts, e.g. in foo.cpp:
#include "common.h"
namespace BLK2
{
int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
int Hs, Std, E, Hs1, Tdt; // initialized to 0 by default
}
You may want to use a different type than int, e.g. unsigned long. I'm assuming the initialized values are meant to be const; if not then change int const to extern int and remove the initializer. The initializer would have to go in the definition in the .cpp file.
Avoid the mistake of declaring a non-const, non-extern variable in the header; this causes undefined behaviour if the header is included in two different units.
You access these variables by writing BLK1::Eta for example.
As you surmise it might be considered tidier to use a struct instead of a namespace, although you'd still have to create an instance of the struct which is declared extern in the header, and defined in exactly one .cpp file; and if you are pre-C++11 it's more annoying to provide initializers.
(Of course, even better would be to refactor the code to not use globals. But it might be useful as a first pass to do a direct translation).
Common blocks with the same name overlap each other in memory. You can allocate a chunk of memory, and typecast pointers to it. Another option is to declare them in a union. That is why a union was invented. Certainly once your union is set up, you use extern in the other modules.
Put the following into a common header and an instance of it into module 1.
Add an extern so it can be seen in module 2.
union blk1
{
struct module_1_view
{
double gw(200);
double eta(4096);
double t(4096);
double phi(200);
double w(200);
}
struct module_2_view
{
double parameters(8592); // 200 + 4096 + 4096 + 200
double w_status(200);
}
}
Imagine module 1 being responsible for loading some set of doubles from a file into the the variables in the module_1_view. Once those parameters are loaded and validated, module 2 is called, which accesses the parameters from the module 2 view. Nearly all of them are accessed via the parameters variable, except for the w_status, which is actually 200 indicators that indicate something about the success or validation of the parameters.
The key point is that module 1 and 2 access the same chunk of memory (hence the union) and they use their own set of variable names.
I can't speak directly to Fortran, but if you want to make a variable accessible throughout the entire program in c/c++, extern is the keyword you are looking for.
Extern is a C style way of sharing data. C++ would push you into OO design, of which a variable that is tightly coupled to many objects isn't good OO.
If you are trying to do C++ things on top of legacy code, sometimes static methods, which are passed pointers to your C++ class can act as wrappers. Heres a simple example of that:
extern int _magicVariable;
static void call( void* klass )
{
((MyClass*)klass)->functionCall( _magicVariable );
}
Inside MyClass, you'll need to name void call( void* ) as a friend. Now the legacy code can call(void*) with a pointer to your class, passing in the _magicVariable into your OO design. From there c++ will do its thing.
The bottom line is you have a lot of ways to accomplish the task, try to do what makes sense based on your desired code structure.
Related
Is there any way (such as compiler flag) to set ALL local variables const automatically without the specifier in C/C++/Objective-C? Just like let semantics in functional languages.
Because I want to set const to all local variables, but it's too annoying and makes code less readable. If I can set all local variables const by default, and I can set some variables mutable manually, it would be great for me. But I never heard about it.
If you know something please let me know.
Edit
I thought a little more about this after reading responses. And I strongly agree to it would disrupt strong C convention (or standard?) because it's already defined as mutable by default.
So my idea is becoming into another form. Kind of static analyzer. Not compiler.
if some tool can check reassigned local variables, and can define any mechanism marking mutable variable (for example, a specific empty preprocessor symbol), it would be perfect tool for me. And also, it won't disrupt C conventions.
So I changed question title a little and added this text.
... errr sort of by employing macros:
int main () {
#define int const int
#define float const float
int x = 5;
float y = 5.3;
#undef int
#undef float
return 0;
}
you can even separate these def's and undef's into two different headers, so that your code would look a bit cleaner:
int main () {
#include "all_vars_const_begin.h"
int x = 5;
float y = 5.3;
#include "all_vars_const_end.h"
return 0;
}
But i'm not sure if this style is Ok.
I'm writing code in Visual C++ and I need to use a global variable. I know it's generally not a good idea, but in this case, it is necessary. I have created the variable and it is accessible from the function that needs it, but I can't figure out how to give it an initial value.
in the .h file it looks like
extern int lversion;
and in the .cpp file it looks like
int lversion;
How can I give this variable an initial value of 0?
Adding these two lines in your .h and .cpp files respectively will allow you to initialize a global variable.
.h:
extern int Val;
.cpp:
int Val = 0;
The variable does have initial value 0 as it is. Globals and statics are value-initialized unless otherwise specified. (for an int, it will be 0)
If you want any other value, you can specify it:
In the cpp file:
int lversion= 3;
or
int lversion(3);
but for a value of 0 there's no point being this verbose.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ - enum vs. const vs. #define
Before I used #define I used to create constants in my main function and pass them where they were needed. I found that I passed them very often and it was kind of odd, especially array sizes.
More recently I have been using #define for the reason that I don't have to pass constants in my main to each individual function.
But now that I think of it, I could use global constants as well, but for some reason I have been a little hesitant towards them.
Which is the better practice: global constants or #define?
A side question, also related: Is passing constants from my main as I described a bad practice?
They don't do quite the same thing. #define lets you affect the code at compilation time, while global constants only come into effect at runtime.
Seeing as #define can only give you extra trouble because there's no checking going on with how you use it, you should use global constants when you can and #define when you must. It will be safer and more readable that way.
As for passing constants from main, it's not unreasonable because it makes the called functions more flexible to accept an argument from the caller than to blindly pull it out of some global. Of course it the argument isn't really expected to change for the lifetime of the program you don't have much to gain from that.
Using constants instead of #define is very much to be preferred. #define replaces the token dumbly in every place it appears, and can cause all sorts of unintended consequences.
Passing values instead of using globals is good practice. It makes the code more flexible and modular, and more testable. Try googling for "parameterise from above".
You should never use either #defines or const variables to represent array sizes; it's better to make them explicit.
Instead of:
#define TYPICAL_ARRAY_SIZE 4711
int fill_with_zeroes(char *array)
{
memset(array, 0, TYPICAL_ARRAY_SIZE);
}
int main(void)
{
char *za;
if((za = malloc(TYPICAL_ARRAY_SIZE)) != NULL)
{
fill_with_zeroes(za);
}
}
which uses a (shared, imagine it's in a common header or something) #define to communicate the array size, it's much better to just pass it to the function as a real argument:
void fill_with_zeroes(char *array, size_t num_elements)
{
memset(array, 0, num_elements); /* sizeof (char) == 1. */
}
Then just change the call site:
int main(void)
{
const size_t array_size = 4711;
char *za;
if((za = malloc(array_size)) != NULL)
{
fill_with_zeroes(za, array_size);
}
}
This makes the size local to the place that allocated it, there's no need for the called function to magically "know" something about its arguments that is not communicated through its arguments.
If the array is non-dynamically allocated, we can do even better and remove the repeated symbolic size even locally:
int main(void)
{
char array[42];
fill_with_zeroes(array, sizeof array / sizeof *array);
}
Here, the well-known sizeof x / sizeof *x expression is used to (at compile-time) compute the number of elements in the array.
Constants are better. The only difference between the two is that constants are type-safe.
You shouldn't use values defined with #define like const parameters. Defines are used mostly to prevent the compiler to compile some parts of code depending on your needings at compile time (platform dependent choices, optimization at compile time, ).
So if you are not using define for these reasons avoid that and use costant values.
I'm writing porting file-io set of functions from c into a c++ class. "Magic numbers" (unnamed constants) abound.
The functions read a file header which has a number of specific entries whose locations are currently denoted by magic numbers.
I was taught by a veteran programmer a couple years back that using "magic numbers" is inherently evil, and thus, I have since tried to avoid using unnamed constants in my port. So I want to create some sort of list of constants of where the entries are stored.
So far I've come up with two solutions that seem relatively safe -- use a namespace enclosed set of constants or a namespace enclosed enum.
Can I use either solution safely? Would there be any advantages to one over the other?
e.g.
OPTION 1
namespace hdr_pos {
const unsigned int item_1_pos=4;
const unsigned int item_2_pos=8;
const unsigned int item_3_pos=12;
const unsigned int item_4_pos=24;
const unsigned int item_5_pos=32;
};
OPTION 2
namespace hdr_pos {
enum e {
item_1_pos=4,
item_2_pos=8,
item_3_pos=12,
item_4_pos=24,
item_5_pos=32
};
};
Is there anyway to prevent duplicates, to catch if I change the positions due to a future update to the file header, but forget to change one of them?
Please keep this factual and non-subjective. If there is no advantage you know of, feel free to answer that.
Note: I would use more descriptive names, of course, in my actual implementation; I just called things item_<#>_... for examples sake...
I can see two advantages to using an enum. First, some debuggers can translate constants back into enum variable names (which can make debugging easier in some cases). Also, you can declare a variable of an enumerated type which can only hold a value from that enumeration. This can give you an additional form of type checking that you wouldn't have simply by using constants.
Checking to see if a value is duplicated might depend on your particular compiler. The easiest way to do so would probably be to write an external script that will parse your enum definition and report whether or not a value is duplicated (you can run this as part of your build process if you like).
I've dealt with this situation before, for error codes.
I have seen people using enums for error codes, and this pose some issues:
you can assign an int to the enum that doesn't not correspond to any value (too bad)
the value itself is declared in a header, meaning that error code reassignment (this happens...) breaks code compatibility, you also have to take care when adding elements...
you have to define all codes in the same header, even if often times some code are naturally restricted to a small portion of the application, because enums cannot be "extended"
there is no check that a same code is not assigned twice
you cannot iterate over the various fields of an enum
When designing my error codes solution, I thus chose another road: constants in a namespace, defined in source files, which address points 2 and 3. To gain in type safety though, the constants are not int, but a specific Code class:
namespace error { class Code; }
Then I can define several error files:
// error/common.hpp
namespace error
{
extern Code const Unknown;
extern Code const LostDatabaseConnection;
extern Code const LostNASConnection;
}
// error/service1.hpp
// error/service2.hpp
I didn't solved the arbitrary cast issue though (constructor is explicit, but public), because in my case I was required to forward error codes returned by other servers, and I certainly didn't want to have to know them all (that would have been too brittle)
However I did thought about it, by making the required constructor private and enforcing the use of a builder, we're even going to get 4. and 5. in a swoop:
// error/code.hpp
namespace error
{
class Code;
template <size_t constant> Code const& Make(); // not defined here
class Code: boost::totally_ordered<Code>
{
public:
Code(): m(0) {} // Default Construction is useful, 0 is therefore invalid
bool operator<(Code const& rhs) const { return m < rhs.m; }
bool operator==(Code const& rhs) const { return m == rhs.m; }
private:
template <size_t> friend Code const& Make();
explicit Code(size_t c): m(c) { assert(c && "Code - 0 means invalid"); }
size_t m;
};
std::set<Code> const& Codes();
}
// error/privateheader.hpp (inaccessible to clients)
namespace error
{
std::set<Code>& PrivateCodes() { static std::set<Code> Set; return Set; }
std::set<Code> const& Codes() { return PrivateCodes(); }
template <size_t constant>
Code const& Make()
{
static std::pair< std::set<Code>::iterator, bool > r
= PrivateCodes().insert(Code(constant));
assert(r.second && "Make - same code redeclared");
return *(r.first);
}
}
//
// We use a macro trick to create a function whose name depends
// on the code therefore, if the same value is assigned twice, the
// linker should complain about two functions having the same name
// at the condition that both are located into the same namespace
//
#define MAKE_NEW_ERROR_CODE(name, value) \
Make<value>(); void _make_new_code_##value ();
// error/common.cpp
#include "error/common.hpp"
#include "privateheader.hpp"
namespace error
{
Code const Unkown = MAKE_NEW_ERROR_CODE(1)
/// ....
}
A tad more work (for the framework), and only link-time/run-time check of the same assignment check. Though it's easy to diagnose duplicates simply by scanning for the pattern MAKE_NEW_ERROR_CODE
Have fun!
The title of your question suggests that the main reason you have doubts about using a enum is that your constants are non-iterative. But in C++ enum types are non-iterative already. You have to jump through quite a few hoops to make an iterative enum type.
I'd say that if your constants are related by nature, then enum is a pretty good idea, regardless of whether the constants are iterative or not. The main disadvantage of enums though is total lack of type control. In many cases you might prefer to have strict control over the types of your constant values (like have them unsigned) and that's something enum can't help you with (at least yet).
One thing to keep in mind is that you can't take the address of an enum:
const unsigned* my_arbitrary_item = &item_1_pos;
If they're purely constants and require no run-time stuff (like can't init enum with non-enum value) then they should just be const unsigned ints. Of course, the enum is less typing, but that's besides the point.
I've come up with a solution to a problem but I'm not sure if it'll always work or just on my compiler. First, the problem: I've noticed in a number of situations it's desirable to have a template class that gets re-instantiated each time it's used even when given the same types (say your template class has static members that are initialized to function calls that have some important side effect -- and you want this side effect to be done every time the template is used). The easy way to do this is to give your template an extra integer parameter:
template<class T, class U, int uniqueify>
class foo
{
...
}
But now you have to manually make sure that every time you use foo you pass it a different value for uniqueify. The naive solution is to use __LINE__ like this:
#define MY_MACRO_IMPL(line) foo<line>
#define MY_MACRO MY_MACRO_IMPL(__LINE__)
This solution has an issue though -- __LINE__ gets reset for each translation unit. So if two translation units use the template on the same line, the template only gets instantiated once. That may seem unlikely, but imagine how difficult to debug the compiler error it would be if it did happen. Similarly you could try using __DATE__ as a parameter somehow, but that only has seconds precision and it's the time when compiling started, not when it reaches that line, so if you're using a parallel version of make it's rather plausible to have two translation units with the same __DATE__.
Another solution is that some compilers have a special non-standard macro, __COUNTER__ that starts at 0 and increments every time you use it. But it suffers from the same problem -- it gets reset for each invocation of the preprocessor, so it gets reset each translation unit.
Yet another solution, is to use __FILE__ and __LINE__ together:
#define MY_MACRO_IMPL(file, line) foo<T, U, file, line>
#define MY_MACRO MY_MACRO_IMPL(T, U, __FILE__, __LINE__)
But you can't pass char literals as template parameters according to the standard because they don't have external linkage.
Even if this did work, whether __FILE__ contains the absolute path to the file or just the name of the file itself isn't defined in the standard, so if you had two identical named files in different folders, this could still break. So here is my solution:
#ifndef toast_unique_id_hpp_INCLUDED
#define toast_unique_id_hpp_INCLUDED
namespace {
namespace toast {
namespace detail {
template<int i>
struct translation_unit_unique {
static int globally_unique_var;
};
template<int i>
int translation_unit_unique<i>::globally_unique_var;
}
}
}
#define TOAST_UNIQUE_ID_IMPL(line) &toast::detail::translation_unit_unique<line>::globally_unique_var
#define TOAST_UNIQUE_ID TOAST_UNIQUE_ID_IMPL(__LINE__)
#endif
Why this works isn't really clear without a usage example, but first an overview. The key insight I had was to see that every time you make a global variable or a static member variable, you're creating a program wide unique number in the form of the address of that variable. So this gives us a unique number that's available at compile time. __LINE__ makes sure we won't get clashes within the same translation unit, and the outer anonymous namespace makes sure the variables are different instances (and thus get differing addresses) across translation units.
Example usage:
template<int* unique_id>
struct special_var
{
static int value;
}
template<int* unique_id>
int special_var<unique_id>::value = someSideEffect();
#define MY_MACRO_IMPL(unique_id) special_var<unique_id>
#define MY_MACRO MY_MACRO_IMPL(TOAST_UNIQUE_ID)
And foo.cpp becomes:
#include <toast/unique_id.hpp>
...
typedef MY_MACRO unique_var;
typedef MY_MACRO unique_var2;
unique_var::value = 3;
unique_var2::value = 4;
std::cout << unique_var::value << unique_var2::value;
Despite being the same template, and the user providing no differentiating parameters, unique_var and unique_var2 are distinct.
I'm mostly worried about the address in of the variable in the anonymous namespace actually being available at compile time. Technically, an anonymous namespace is like declaring internal linkage, and template parameters can't have internal linkage. But the way the standard says to treat anonymous namespaces is just like the variable was declared as part of a namespace with a program-wide unique name, which means that technically it does have external linkage, even though we don't usually think of it as such. So I think the standard is on my side, but I'm not sure.
I don't know if I've done the best job of explaining why this would be useful, but for the sake of this discussion, it is, I swear ;)
This technique is not safe in general, for two reasons.
__LINE__ can be equal on two different lines in the same translation unit, either through #line directives, or (more commonly) through use on the same line number in multiple header files.
You will have ODR violations if you use TOAST_UNIQUE_ID or anything derived from it within in inline function or template definition in a header file.
That said, if you never use this in header files, and don't use #line in your main source file, and only use the macro once per line, it seems safe. (You can remove that last restriction by switching from __LINE__ to __COUNTER__.)
This should be safe - but simpler way would be to just use FILE. Also, an int isn't enough on a 64-bit platform. Use an intptr_t:
template<const char *file, int line>
class unique_value {
static char dummy;
unique_value() { }
public:
static intptr_t value() { return (intptr_t)&dummy; }
};
#define UNIQUE_VALUE (unique_value<__FILE__, __LINE__>::value())
Further, keep in mind that this will break down when used within a macro or template.
Also, templates with static values with side effects are a bad idea - remember that the side effects occur in arbitrary order, before main() is called - and burying initialization side effects in random functions is not very good for maintainability.