473,847 Members | 1,689 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

#define can't be inside function?

"#define" can only be inside the global scope before main() function.
"#if" can be tested after "#define" is executed. The problem is that
"#define" can't be inside main() function. I do not wish to create multiple
functions which they look almost identical in C++ source code. The C++
compiler should be able to compile one Test() function into two almost
identical functions before they are translated into the machine language
object. The machine language object has two Test() functions, but they
exclude some line parts. First Test() function uses printf("1\n") and
second Test() function uses printf("2\n").
It is the same example that you use MACRO to test the conditional
defines before some lines can be inserted or removed.
If there is no way to test it at compile time, I would have to manual
pasting one Test() function into multiple Test() functions in C++ source
code. Please advise.

Bryan Parkoff

#include <stdio.h>

#define A 1

void Test(void)
{
#if (A == 1)
printf("1\n");
#endif

#if (A == 2)
printf("2\n");
#endif
}

int main(void)
{
Test();
#undef A
#define A 2
Test();

return 0;
}
Jul 23 '05 #1
18 8935

"Bryan Parkoff" <no****@nospam. com> skrev i en meddelelse
news:qd******** *****@newssvr11 .news.prodigy.c om...
"#define" can only be inside the global scope before main() function.
This is wrong. #defines can be placed everywhere - it just has to be on a
line by itself (with "#" being the first character of that line).
"#if" can be tested after "#define" is executed. The problem is that
"#define" can't be inside main() function. I do not wish to create
multiple functions which they look almost identical in C++ source code.
The C++ compiler should be able to compile one Test() function into two
almost identical functions before they are translated into the machine
language object. The machine language object has two Test() functions,
but they exclude some line parts. First Test() function uses
printf("1\n") and second Test() function uses printf("2\n").
It is the same example that you use MACRO to test the conditional
defines before some lines can be inserted or removed.
If there is no way to test it at compile time, I would have to manual
pasting one Test() function into multiple Test() functions in C++ source
code. Please advise.

Bryan Parkoff

[snip]

/Peter
Jul 23 '05 #2
Bryan Parkoff <no****@nospam. com> wrote:
| "#define" can only be inside the global scope before main() function.
| "#if" can be tested after "#define" is executed. The problem is that
| "#define" can't be inside main() function. I do not wish to create multiple
| functions which they look almost identical in C++ source code. The C++
| compiler should be able to compile one Test() function into two almost
| identical functions before they are translated into the machine language
| object. The machine language object has two Test() functions, but they
| exclude some line parts. First Test() function uses printf("1\n") and
| second Test() function uses printf("2\n").

That's what templates are for:
template <int a>
void foo()
{
if (a == 1)
printf("1\n");
if (a == 2)
printf("2\n");
}

int main()
{
foo<1>();
foo<2>();
}

| It is the same example that you use MACRO to test the conditional
| defines before some lines can be inserted or removed.

You could of course use some form of macro magic, but templates are
usually prettier.

| If there is no way to test it at compile time, I would have to manual
| pasting one Test() function into multiple Test() functions in C++ source
| code. Please advise.

Compilers today do such optimizations. My g++ do. Do you want to test
things at compile time or before compile time?

--
Robert Bauck Hamar
Jul 23 '05 #3
Robert Bauck Hamar,

I want to say thank you very much for the information. I try to add
comment so you can understand better. Please look at my example. It has
multiple functions. They are almost identical. Sometimes, I use B++, but
sometimes, I use C++. I do not wish to use Test1(), Test2(), and Test3(),
but I use one function as Test(). I expect that Test1(), Test2(), and
Test3() stop to exist in the source code. Please read second paragraph
below my example.

void Test(void)
{
A++;
B++;
C++;
}

void Test1(void)
{
A++;
}

void Test2(void)
{
A++;
B++;
}

void Test3(void)
{
A++;
C++;
}

If Test() contains "if (A == XX)", it should never exist in the machine
language object in both debug version and release version. I expect C++
compiler to remove "if (A == XX)" before A++, B++, and/or C++ can be stored
in the machine language object. Look at my example below. Please read
third paragraph below my example.

int main(void)
{
A = 1;
Test(); // Put A++ only (B++ and C++ are excluded) without "if (A ==
XX)"
A = 2;
Test(); // Put A++ and B++ only (C++ is excluded) without "if (A == XX)"
A = 3;
Test(); // Put A++ and C++ only (B++ is excluded) without "if (A == XX)"
A = 0;
Test(); // Put A++, B++, and C++ without "if (A == XX)"
}

void Test(void)
{
if (A == 1)
A++;
if (A == 2)
B++;
if (A == 3)
C++;
}

After my C++ source code is compiled into machine language object in
both debug version and release version, "if (A == XX)" is removed
automatically, A++, B++, and/or C++ can be preserved or removed. It would
reduce x86 instructions and improve performance.
I know that "if (A == XX)" do not work so it needs one or more variables
like "if (B == XX)" and "if (C == XX)" so they can test correctly.
Do you expect that template is only the answer?

Bryan Parkoff

<ro**********@i fi.uio.no> wrote in message
news:d7******** **@readme.uio.n o...
Bryan Parkoff <no****@nospam. com> wrote:
| "#define" can only be inside the global scope before main()
function.
| "#if" can be tested after "#define" is executed. The problem is that
| "#define" can't be inside main() function. I do not wish to create
multiple
| functions which they look almost identical in C++ source code. The C++
| compiler should be able to compile one Test() function into two almost
| identical functions before they are translated into the machine language
| object. The machine language object has two Test() functions, but they
| exclude some line parts. First Test() function uses printf("1\n") and
| second Test() function uses printf("2\n").

That's what templates are for:
template <int a>
void foo()
{
if (a == 1)
printf("1\n");
if (a == 2)
printf("2\n");
}

int main()
{
foo<1>();
foo<2>();
}

| It is the same example that you use MACRO to test the conditional
| defines before some lines can be inserted or removed.

You could of course use some form of macro magic, but templates are
usually prettier.

| If there is no way to test it at compile time, I would have to
manual
| pasting one Test() function into multiple Test() functions in C++ source
| code. Please advise.

Compilers today do such optimizations. My g++ do. Do you want to test
things at compile time or before compile time?

--
Robert Bauck Hamar

Jul 23 '05 #4
Robert Bauck Hamar,

I want to let you know that your example code does not work. If
template function reads "1" and "2", then it will execute "2" twice. It
never shows "1" before "2". Look at my example that is similiar yours.

#include <stdio.h>

template <int A>
void Test(void)
{
if (A == 1)
printf("1\n");
if (A == 2)
printf("2\n");
if (A == 3)
printf("3\n");
printf("\n");
}

int main(void)
{
Test<1>();
Test<2>();
Test<3>();

return 0;
}

Output shows "3" in first line, second line, and third line. Is there a
fix?

Bryan Parkoff
<ro**********@i fi.uio.no> wrote in message
news:d7******** **@readme.uio.n o...
Bryan Parkoff <no****@nospam. com> wrote:
| "#define" can only be inside the global scope before main()
function.
| "#if" can be tested after "#define" is executed. The problem is that
| "#define" can't be inside main() function. I do not wish to create
multiple
| functions which they look almost identical in C++ source code. The C++
| compiler should be able to compile one Test() function into two almost
| identical functions before they are translated into the machine language
| object. The machine language object has two Test() functions, but they
| exclude some line parts. First Test() function uses printf("1\n") and
| second Test() function uses printf("2\n").

That's what templates are for:
template <int a>
void foo()
{
if (a == 1)
printf("1\n");
if (a == 2)
printf("2\n");
}

int main()
{
foo<1>();
foo<2>();
}

| It is the same example that you use MACRO to test the conditional
| defines before some lines can be inserted or removed.

You could of course use some form of macro magic, but templates are
usually prettier.

| If there is no way to test it at compile time, I would have to
manual
| pasting one Test() function into multiple Test() functions in C++ source
| code. Please advise.

Compilers today do such optimizations. My g++ do. Do you want to test
things at compile time or before compile time?

--
Robert Bauck Hamar

Jul 23 '05 #5
In article <qd************ *@newssvr11.new s.prodigy.com>,
no****@nospam.c om says...
"#define" can only be inside the global scope before main() function.
"#if" can be tested after "#define" is executed. The problem is that
"#define" can't be inside main() function.
What makes you think that? I'm not sure it does much (if anything) to
help the problem you cite below, but it's entirely possible to do a
#define inside of main (or another function of your choice).
I do not wish to create multiple
functions which they look almost identical in C++ source code.
Indeed -- one of the reasons for using functions is to avoid code
duplication.
#include <stdio.h>

#define A 1

void Test(void)
{
#if (A == 1)
printf("1\n");
#endif

#if (A == 2)
printf("2\n");
#endif
}

int main(void)
{
Test();
#undef A
#define A 2
Test();

return 0;
}


There are quite a few ways of handling this. The first (and most
obvious) would be to simply pass A as a parameter:

#define A 1

void Test(int A) {
printf("%d\n", A);
}

int main() {
Test(A); // prints 1

#undef A
#define A 2

Test(A); // prints 2

return 0;
}

If, for some reason, it's necessary that you print a string literal
instead of converting A from an int at run-time, you can do that with
the preprocessor:

#include <stdio.h>

#define make_string(a) #a
#define str(x) make_string(x)

#define Test(A) printf(str(A) "\n")

int main() {
#define A 1
Test(A);
#undef A
#define A 2
Test(A);
return 0;
}

The make_string(x)/str(x) is a fairly well-known pre-processor idiom.
The '#' is the pre-processor's stringizing operator, which produces a
quoted string literal of whatever it's applied to. The extra level of
macro expansion makes the preprocessor expand the parameter out to
its value instead of its name. Once we have the value in a string, we
put it next to the "\n" string, so the compiler will concatenate the
two into a single string for us.

If you really can't pass A as a parameter, you can do something like
this:

#include <stdio.h>

#define make_string(a) #a
#define str(x) make_string(x)

#define Test() printf(str(A) "\n")

int main() {
#define A 1
Test();
#undef A
#define A 2
Test();
return 0;
}

Personally, I'd advise against this though -- it usually loses far
more than it gains.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 23 '05 #6
Jerry,

Your previous example below does not work. It only prints "1" in first
line and second line. I can assume that "#undef A" and "#define A 2" are
not working.
#define A 1

void Test(int A) {
printf("%d\n", A);
}

int main() {
Test(A); // prints 1

#undef A
#define A 2

Test(A); // prints 2

return 0;
}


Bryan Parkoff
Jul 23 '05 #7
In article <yI************ *@newssvr30.new s.prodigy.com>,
no****@nospam.c om says...
Jerry,

Your previous example below does not work. It only prints "1" in first
line and second line. I can assume that "#undef A" and "#define A 2" are
not working.


I think I must have accidentally copied and pasted the wrong version
-- as it stands right now, it doesn't even compile -- this:

#define A 1

void Test(int A) {
// ...

expands to:

void Test(int 1) {

which isn't allowed. Fixing that gives:

#include <stdio.h>

#define A 1

void Test(int a) {
printf("%d\n", a);
}

int main() {
Test(A); // prints 1

#undef A
#define A 2

Test(A); // prints 2

return 0;
}

which prints out:

1
2

as it should. If you're getting 1 twice as you describe above, then
I'd have to guess it's a problem with (the version of) whatever
compiler you're using.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 23 '05 #8
Jerry,

Yes, it still gets "1" twice. I use Microsoft Visual C++ 6.0. Do you
know if I should be able to fix this problem by using C++ Compiler's option?
Or...do you suggest me to use another C++ Compiler?

Bryan Parkoff

"Jerry Coffin" <jc*****@taeus. com> wrote in message
news:MP******** *************** *@news.sunsite. dk...
In article <yI************ *@newssvr30.new s.prodigy.com>,
no****@nospam.c om says...
Jerry,

Your previous example below does not work. It only prints "1" in
first
line and second line. I can assume that "#undef A" and "#define A 2" are
not working.


I think I must have accidentally copied and pasted the wrong version
-- as it stands right now, it doesn't even compile -- this:

#define A 1

void Test(int A) {
// ...

expands to:

void Test(int 1) {

which isn't allowed. Fixing that gives:

#include <stdio.h>

#define A 1

void Test(int a) {
printf("%d\n", a);
}

int main() {
Test(A); // prints 1

#undef A
#define A 2

Test(A); // prints 2

return 0;
}

which prints out:

1
2

as it should. If you're getting 1 twice as you describe above, then
I'd have to guess it's a problem with (the version of) whatever
compiler you're using.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #9
In article <Z7************ **@newssvr30.ne ws.prodigy.com> ,
no****@nospam.c om says...
Jerry,

Yes, it still gets "1" twice. I use Microsoft Visual C++ 6.0. Do you
know if I should be able to fix this problem by using C++ Compiler's option?
Or...do you suggest me to use another C++ Compiler?


This seems very strange -- I originally tested it with VC++ 7.1, but
doing a quick check with 6.0, the result is identical. Just for fun,
I also tested it with Borland 5.5 and Comeau 4.3.4, all with
identical results.

Just for fun, let's try a little exercise. I've rewritten the code to
eliminate the header, and just declare printf directly -- generally a
poor idea, but helpful for the moment.

#define A 1

extern int printf(char const *, ...);

void Test(int a) {
printf("%d\n", a);
}

int main() {
Test(A); // prints 1

#undef A
#define A 2

Test(A); // prints 2

return 0;
}

Now, what we want to do is ONLY preprocess that code to see what it
produces. To do that, use cl /E whatever.c, and it'll display the
preprocessed output. That's why we got rid of stdio.h -- it will have
lots of extra "stuff" we don't care about that gets in the way of
seeing what we do care about. Here's the output I get:

#line 1 "ize.c"
extern int printf(char const *, ...);

void Test(int a) {
printf("%d\n", a);
}

int main() {
Test(1);


Test(2);

return 0;
}

One remote possibility occurs to me: what (if any) service pack have
you applied to Visual Studio? It's remotely possible that this got
fixed somewhere along the line, and you _could_ be running a version
from before its getting fixed. If so, simply applying the latest
service pack may suddenly make things work for you.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

97
27832
by: s | last post by:
Can I do this: #define MYSTRING "ABC" .. .. .. char mychar = MYSTRING; .. .. ..
34
3699
by: Dennis | last post by:
I would like to dynamically allocate in a sub a 2 dimensional Array float *myarray = new float ; of course I get an error. How do you allocate a 2D array using the New operator? I currently use static float gxy;
15
2187
by: Jorge Naxus | last post by:
Hello I would like to write a macro like that: #ifdef DEBUG #define printj(...) printf(...) #else #printj(...) #endif
3
9811
by: robin liu | last post by:
What's the difference between these two declarations ? 1) typedef void (*pf)(void); 2) typedef void f(void); the first declaration is define a function pointer, what is the second ? define a function model? And can use the second declaration to define a function pointer as follow:
19
2431
by: Sensei | last post by:
Hi! I'm concerned about the legality of such a definition: #define funcX funcY where funcX belongs to the *standard* C functions. Is it legal to do this? The standard says "any function declared in a header may be additionally implemented as a macro defined in the header, so a library function should not be declared explicitly if its header is included". Is this applicable to standard functions? And, what if the definition
4
2437
by: Mohammad Omer Nasir | last post by:
I was read Linux kernel code in which I saw few define macro defines in functions. The snap of the function is following and file name "err_ev6.c". static int ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, u64 c_stat, u64 c_sts, int print) { char *sourcename = { "UNKNOWN", "UNKNOWN", "UNKNOWN", "MEMORY", "BCACHE", "DCACHE",
12
4642
by: djhong | last post by:
Following is a snippet of a header file. Here, #define are inside struct evConn{} Any advantage of putting them inside struct block? Looks like there is no diff in scoping of each identifier between inside and outside struct block.... typedef struct evConn { evConnFunc func; void * uap;
4
1469
by: rasmidas | last post by:
There are two different directories. sparse/src/stk/dmg_apiutil and sparse/src/stk/dmg_meta_doc Inside these two directories there are lot of C++ files. I have written a function:
2
8003
by: jiuguangw | last post by:
Hi, I currently have a application which needs to dynamically define a function (post-compilation). In Lisp, this can be done by embedding a function definition inside a string, and call eval(string). In C++, I thought about using #define macros, like so: #define some_function() int a = 3; int b = 5; cout << a + b << endl; int main(int argc, char *argv) {
0
9730
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10647
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10706
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10338
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7882
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7056
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4528
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4119
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3164
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.