Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

c++ preprocess directives

Posted on 2006-11-16
12
Medium Priority
?
611 Views
Last Modified: 2012-08-13
Hello,

I was trying to use #define directives to make a base directory for all my include files. So the idea was:

Compile the program with a flag -D__BASE__=/some/path/to/base/ and then add this before the filename in the #include.
So basically:

#include __BASE__ "Foo.h"

This does not work (of course), but I searched the internet and found some information about directives and I came up with this:

#define CONCAT(a, b) a b
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define ROOT TOSTRING(__BASE__)
#include CONCAT(ROOT, "Foo.h")

But this does not work either. I think the problem lies in the fact that I do not precisely know how this is processed (although it looks very simple), anyway there are 'tokens' and 'strings' and it just seems I cannot concat two strings.
For example I get things like

"/some/path/" "Foo.h"

or sometimes I even get /some/path/Foo.h, but when using it on the #include it says: /some/path/: No such file or directory, in other words, it only took the first part. So I guess the preprocessor just replaces everything and does not really DO anything.

Anyway, any help would be appreciated. Thank you.

Mark

0
Comment
Question by:ADSLMark
  • 5
  • 3
  • 2
  • +1
12 Comments
 
LVL 22

Accepted Solution

by:
grg99 earned 80 total points
ID: 17961522

    try   #include "__BASE__/./foo.h"

or  try   #include "__BASE__##foo.h"

You may have better luck  passing in the include directory with -I
0
 
LVL 10

Author Comment

by:ADSLMark
ID: 17963634
Ok, well that did not work, but I found something else.

If you want to concat a '/' with something then you get an error. For example:

#define BASE path
#define SLASH /

#define CONCAT(x,y) x##y
#define TOCONCAT(x,y) CONCAT(x,y)

#define PATH TOCONCAT(BASE,SLASH)

>> pasting "path" and "/" does not give a valid preprocessing token

Is there someone who knows the solution to this?

Mark
0
 
LVL 10

Author Comment

by:ADSLMark
ID: 17963733
Ok, i have this really stupid solution now:

#define BASE /some/pa

#define STR(x) #x
#define TOSTR(x) STR(x)

#define CONCAT(x,y) x##y
#define TOCONCAT(x,y) CONCAT(x,y)

#include TOSTR(TOCONCAT(__BASE__,th/Foo.h))

Since i pass the BASE variable through the command line when compiling, i will not use the full path in the #include (that was the whole idea). So now i split halfway a word, of course i could make some nicer split, but this is kinda weird solution (though it works).

I would love to see other solutions which allow me to make a separation between BASE and FILE, ie. BASE=some/path and FILE=/Foo.h

Mark
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:grg99
ID: 17965470

-I?

0
 
LVL 14

Expert Comment

by:wayside
ID: 17967282
Why not just use

-I/some/path/to/base/

(or whatever your compiler's option is to set an include directory)?
0
 
LVL 14

Expert Comment

by:wayside
ID: 17967287
D'oh, sorry grg99, I somehow didn't see your response when I put mine in.
0
 
LVL 10

Author Comment

by:ADSLMark
ID: 17967540
I do not want to use -I. The system is going to be pretty big so -I won't do (in this case).
0
 
LVL 22

Expert Comment

by:grg99
ID: 17967691
>The system is going to be pretty big so -I won't do (in this case).

Any particular reason it won't do?   There are programs that encompass hundreds of source files and they use -I

Not that -I is a particularly good solution, but it's there, and does the job.
0
 
LVL 10

Author Comment

by:ADSLMark
ID: 17967730
Ok, whatever, I won't use it. I want to use it in the way I sketched. If you are not ok with that, fine.
Let me rephrase the question for you:

How can i add a special character?
For example:

#define FOO /foo
#define BAR /bar

#define STR(x) #x
#define TOSTR(x) STR(x)

#define CONCAT(x,y) x##y
#define TOCONCAT(x,y) CONCAT(x,y)

#define ANSWER TOSTR(TOCONCAT(FOO, BAR))

I want ANSWER to be /foo/bar and the first character of BAR is ALWAYS a / (might be a ., but that comes down to the same problem).

Any idea?
0
 
LVL 15

Expert Comment

by:efn
ID: 17970586
I followed the code you posted with

#include ANSWER

and the compiler complained that it couldn't find the file /foo/bar.  When I created this file, the compiler opened it and compiled it.  So it seems that you have solved the problem you originally stated.  What special character do you want to add where and why?
0
 
LVL 10

Author Comment

by:ADSLMark
ID: 17970884
I truly get the error:

test.cpp:12:1: pasting "foo" and "/" does not give a valid preprocessing token

I used "g++ test.cpp" which sounds as simple as it can get.
My test environment looks like this:

-- test.cpp
#define FOO /path/to/ans
#define BAR /ans.h

#define STR(x) #x
#define TOSTR(x) STR(x)

#define CONCAT(x,y) x##y
#define TOCONCAT(x,y) CONCAT(x,y)

#define ANSWER TOSTR(TOCONCAT(FOO, BAR))

#include ANSWER

#include <iostream>

int main(int argc, char** args)
{
  std::cout << ANS << std::endl;
  return 0;
}

-- ans.h
#define ANS 1234

Maybe i should use a different compiler?

Mark
0
 
LVL 15

Assisted Solution

by:efn
efn earned 80 total points
ID: 17972922
I used Microsoft Visual C++ 2005 Express Edition.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question