Re: [boost] Preprocessot question

a.c #include "err.h" static const int err_tag = err_tag_a_c; enum {err_bad_foobar=1, err_missing_baz, ... };
and you use the errors as follows:
long err = ERR(missing_baz); How is it going to prevent duplication. Suppose, somewhere in a.c if I write long err = ERR(missing_baz), what happens?
with the macro ERR defined in err.h as:
#define ERR(x) ((err_tag * 65536L) + err_##x)
-----Original Message----- From: Martin Bonner [mailto:martin.bonner@pitechnology.com] Sent: Tuesday, August 30, 2005 1:40 AM To: 'Suman Cherukuri' Subject: RE: [boost] Preprocessot question ----Original Message---- From: Suman Cherukuri [mailto:suman@cherukuris.net] Sent: 29 August 2005 22:49 To: boost@lists.boost.org Subject: [boost] Preprocessot question
This probably doesn't belong to boost mailing list, but since boost has a lot of support in preprocessor, there may be someone who can answer my question.
You would have done better to ask this in comp.lang.c.moderated.
I'm using general 'C' compiler in this project (hence I cannot use boost headers). I want to write a macro as follows;
#define ERR(x, y) \ { \ # ifndef ERR##x \ # define ERR##x \ # else \ # error ERR##x already defined\ # endif y = x; \ }
When I compile, I get the error saying, error C2162: expected macro formal parameter on all the preprocessor lines inside the #define ERR(...) body.
Right. You can't write a preprocessor macro that creates preprocessor directives. The #ifndef in your macro will never get parsed.
The reason I want to do something like this is to have some unique numbers in the code (like locators. Don't want to use __FILE__ and __LINE__ for security reasons) and want to capture duplicates at compiletime.
For example if I say in the code, int err = 10000 in one file, I don't want any other engineer to use 10000 in the anywhere else in the code.
So I started writing something like int err = ERR(10000) but got into several compiler problems as I mentioned above.
The problem I see with your solution (assuming it worked), is that if we have two files a.c and b.c, then somebody could write: a.c: ... int err = ERR(10000); ... b.c: ... int err = ERR(10000); ... ... and the check would fail to detect that both files are using the same value :-( The simple solution is to have a err.h which defines a (long) enumeration, and every time you need a new error value, you add to err.h. That is simple, but of course it means you need to recompile everything every time you add a value. The slightly more complex version is that you have an err.h which has an enumeration which is specific to each .c file. (That means you will have to recompile every time you add an .c file, but that is probably bearable.) So err.h might look like: enum { err_tag_a_c=1, err_tag_b_c, .... }; Then each .c file has at the start: a.c #include "err.h" static const int err_tag = err_tag_a_c; enum {err_bad_foobar=1, err_missing_baz, ... }; and you use the errors as follows: long err = ERR(missing_baz); with the macro ERR defined in err.h as: #define ERR(x) ((err_tag * 65536L) + err_##x) To add a new error code, you update the enumeration at the top of file, and use it via the ERR macro. (Which only requires recompiling the file you were changing anyway). Note that I assumed you could use long for your error codes - if you are in the embedded world, that might not be affordable. On the other hand, in the embedded world you can probably live with only 255 different files, and 255 error codes per file. -- Martin Bonner Martin.Bonner@Pitechnology.com Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ, ENGLAND Tel: +44 (0)1223 441434
participants (1)
-
Suman Cherukuri