Solved

c++ preprocess directives

Posted on 2006-11-16
12
608 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
  • +1
12 Comments
 
LVL 22

Accepted Solution

by:
grg99 earned 40 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
Independent Software Vendors: 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 40 total points
ID: 17972922
I used Microsoft Visual C++ 2005 Express Edition.
0

Featured Post

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!

Question has a verified solution.

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

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
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 user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

717 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