473,626 Members | 3,389 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 8915

"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
27766
by: s | last post by:
Can I do this: #define MYSTRING "ABC" .. .. .. char mychar = MYSTRING; .. .. ..
34
3669
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
2168
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
9795
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
2414
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
2429
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
4632
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
1456
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
7874
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
8268
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8202
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
8707
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8510
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...
0
7199
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4093
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2628
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
1
1812
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1512
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.