Discussion:
"PORTING C" > How to assign a value to a define statement?
(too old to reply)
Robby
2010-02-03 17:11:02 UTC
Permalink
Hello,

This question is geared more towards seeking a voice of programming
experience.

I am running into a situation where I need some advice on how to do things.
Perhaps I am seeing this the wrong way. In summary, from main(), I would like
to call a defined macro called "Config_delay_timers", and in that macro I
would like to do some calculations where the result can be assigned to the
value of another #define statement.

Please view the following code:
==========================main.h

#ifndef TEST_H
#define TEST_H

// *** SYSTEM OSCILLATION *** //
#define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
FREQ = (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

#define CURR_SYS_OSC FREQ
#define OSC_PERIOD (1.0/CURR_SYS_OSC)

#endif // TEST_H //

=====================================main.c
#include <stdio.h>
#include "test.h"

int main()
{

Config_delay_timers(8, 2, 21, 8);
//SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);

return 0;
}
===================================

I am getting an error where the compiler complains about FREQ is undefclared.
So how is one supposed to carry out a particular calculation via a define
macro and then further assign this result to other define variables in the
program.

I am thinking of mayby using #ifdef preprocessor command but I don't see how
this would be of any use in this particular case.

All help or reccomendations is very welcome and apprciated. Thanks in advance!
--
Best regards
Roberto
Bo Persson
2010-02-03 17:25:40 UTC
Permalink
Post by Robby
Hello,
This question is geared more towards seeking a voice of programming
experience.
I am running into a situation where I need some advice on how to do
things. Perhaps I am seeing this the wrong way. In summary, from
main(), I would like to call a defined macro called
"Config_delay_timers", and in that macro I would like to do some
calculations where the result can be assigned to the value of
another #define statement.
==========================main.h
#ifndef TEST_H
#define TEST_H
// *** SYSTEM OSCILLATION *** //
#define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
FREQ =
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
#define CURR_SYS_OSC FREQ
#define OSC_PERIOD (1.0/CURR_SYS_OSC)
#endif // TEST_H //
=====================================main.c
#include <stdio.h>
#include "test.h"
int main()
{
Config_delay_timers(8, 2, 21, 8);
//SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
return 0;
}
===================================
I am getting an error where the compiler complains about FREQ is
undefclared. So how is one supposed to carry out a particular
calculation via a define macro and then further assign this result
to other define variables in the program.
Macros don't do variables, they are just text processing.
Post by Robby
I am thinking of mayby using #ifdef preprocessor command but I
don't see how this would be of any use in this particular case.
All help or reccomendations is very welcome and apprciated. Thanks in advance!
If you want a constant value in the program, declare one:

const float FREQ = ...


Bo Persson
Igor Tandetnik
2010-02-03 17:37:15 UTC
Permalink
Post by Robby
I am running into a situation where I need some advice on how to do
things. Perhaps I am seeing this the wrong way. In summary, from
main(), I would like to call a defined macro called
"Config_delay_timers", and in that macro I would like to do some
calculations where the result can be assigned to the value of another
#define statement.
This makes no sense. Macros a just text substitutions, performed at compile time. If you want to calculate a value at run time, you need a variable for it.
Post by Robby
==========================main.h
#ifndef TEST_H
#define TEST_H
// *** SYSTEM OSCILLATION *** //
#define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
FREQ = (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
#define CURR_SYS_OSC FREQ
#define OSC_PERIOD (1.0/CURR_SYS_OSC)
#endif // TEST_H //
=====================================main.c
#include <stdio.h>
#include "test.h"
int main()
{
Config_delay_timers(8, 2, 21, 8);
//SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
return 0;
}
Well, since you are hardcoding all the constants anyway, why not something like this:

#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define FREQ (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

If, on the other hand, you expect these values to change from run to run, then you need real functions to calculate them and real variables to store them.
Post by Robby
So how is one supposed to carry out a particular
calculation via a define macro and then further assign this result to
other define variables in the program.
One is not supposed to.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Robby
2010-02-03 18:57:01 UTC
Permalink
Thank you fellows for your feedback!
--
Best regards
Roberto
Post by Igor Tandetnik
Post by Robby
I am running into a situation where I need some advice on how to do
things. Perhaps I am seeing this the wrong way. In summary, from
main(), I would like to call a defined macro called
"Config_delay_timers", and in that macro I would like to do some
calculations where the result can be assigned to the value of another
#define statement.
This makes no sense. Macros a just text substitutions, performed at compile time. If you want to calculate a value at run time, you need a variable for it.
Post by Robby
==========================main.h
#ifndef TEST_H
#define TEST_H
// *** SYSTEM OSCILLATION *** //
#define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
FREQ = (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
#define CURR_SYS_OSC FREQ
#define OSC_PERIOD (1.0/CURR_SYS_OSC)
#endif // TEST_H //
=====================================main.c
#include <stdio.h>
#include "test.h"
int main()
{
Config_delay_timers(8, 2, 21, 8);
//SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
return 0;
}
#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define FREQ (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
If, on the other hand, you expect these values to change from run to run, then you need real functions to calculate them and real variables to store them.
Post by Robby
So how is one supposed to carry out a particular
calculation via a define macro and then further assign this result to
other define variables in the program.
One is not supposed to.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
.
Robby
2010-02-03 20:47:01 UTC
Permalink
Post by Igor Tandetnik
#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define FREQ (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
"Igor Tandetnik" wrote:

Igor, one thing though, I am trying to create structures that hold only one
type of data which relates to one type of task in my code. Then I would like
to create functions that would manipulate the respective structure
accordingly. So for example, if I am setting up a #define statement to hold
the current system clock... like this:

#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define
CURR_SYS_OSC(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

I would rather create a structure holding this type of data. Then call a
function to manipulate it. I think!!! the way you described it above is sort
of a non OOP approach. Now, now, hold it right there.... don't think I am
saying that you don't know OOP! I know that you and many others here know OOP
and very well too. But what I am trying to reach for here is I would like to
get in the habit of starting to gear my code towards *some* oopness!!!

So what I am saying is, that, isn't there a better and more structured way
of doing... for example my CURR_SYS_OSC calculation.... perhaps creating an
API function which references that #define directive. Mind you, one thing
that doesn't help here is that I am a little confused as what is the
difference between an API call *and* a normal function call *and* when we
create an object and call a function passing a pointer to the object as a
parameter. I know I use them, but again, I am calling these functions without
good "OOP" reasoning.

So for my example, what if I do this, what do you think?
===================================KERNEL.h
#ifndef KERNEL_H
#define KERNEL_H

#define CURR_SYS_OSC (((float)(curr_sys_osc.extCrys/curr_sys_osc.fpllidiv)*
\
(float)(curr_sys_osc.fpllmul/curr_sys_osc.fpllodiv))*1000000)

// Note: OSC_PERIOD is used in other modules too !!!!!!!!
#define OSC_PERIOD (1.0/CURR_SYS_OSC)

typedef struct tag_osc_info
{
float extCrys;
float fpllidiv;
float fpllmul;
float fpllodiv;
}osc_info;

extern osc_info curr_sys_osc;

void compute_curr_sys_osc
(float extCrys, float fpllidiv, float fpllmul, float fpllodiv);

=======================================KERNEL.c
#include "KERNEL.h"
osc_info curr_sys_osc;

// The next line configures the on chip PLL. In anycase this is where I get
the values:
//Externel crystal= 8.0 and the rest: 2.0, 21.0, 8.0
#pragma config FPLLIDIV = DIV_2, FPLLMUL = MUL_21, FPLLODIV = DIV_8

int main(void)
{
compute_curr_sys_osc(8.0, 2.0, 21.0, 8.0);

//.... other code
}


void compute_curr_sys_osc
(float extCrys, float fpllidiv, float fpllmul, float fpllodiv)
{
curr_sys_osc.extCrys = extCrys;
curr_sys_osc.fpllidiv = fpllidiv;
curr_sys_osc.fpllmul = fpllmul;
curr_sys_osc.fpllodiv = fpllodiv;
}
=========================================
And remember I can't make CURR_SYS_OSC a macro, because, OSC_PERIOD needs
CURR_SYS_OSC as a value in its calculation!

Am I getting too complicated for nothing here, or is carrying out any small
calculation or logical process a good habit to do it via a function like I
have done above?

I could just keep on plugging and calling any function and macro anywhere I
can and as long as it compiles I would be able to continue, but I find I am
lacking structure with all of these #defines, #defined macros and functions.
For what reson should each one be specifically used for? For example, why use
defined macros, when we have functions. Inline functions... thats another
one???? Althought, I would like to know when to use what.

PS. I wouldn't want to know how to do everything right away, but what would
be the most appropriate way to do the innitial example of this post?

I sincerely thank you or anyone else for any advice or help in guiding me on
this subject!

Rob
Igor Tandetnik
2010-02-03 21:32:18 UTC
Permalink
Post by Robby
Post by Igor Tandetnik
#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define FREQ
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
Igor, one thing though, I am trying to create structures that hold
only one type of data which relates to one type of task in my code.
Then I would like to create functions that would manipulate the
respective structure accordingly.
Well, if they are compile-time constants, what precisely does it mean to "manipulate" them?
Post by Robby
So for example, if I am setting up
#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define
CURR_SYS_OSC(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
I would rather create a structure holding this type of data. Then
call a function to manipulate it. I think!!!
So, forget about implementation details. Design the interface from the client's point of view: if you somehow magically had a thrid-party library of your dreams doing precisely what you want to do, what would that library's API look like? What calls would you make to it? Then, once you have your ideal interface, fill in the implementation.
Post by Robby
So what I am saying is, that, isn't there a better and more
structured way of doing...
Perhaps. It's hard for me to say, as I have no idea what it is you are trying to achieve. Now, before you go and write a long explanation, note that I'm probably not going to read it: except in very simple and obvious cases, it takes too much effort to understand the problem well enough to offer a good design, so as a rule, I don't give design advice.
Post by Robby
Mind you, one thing that doesn't help here is
that I am a little confused as what is the difference between an API
call *and* a normal function call
None. API is just a collection of functions, usually designed to work together and united by a common theme. An "API call" is just a shorthand for "a call to a function from some API" (it is usually clear from context which API is meant).
Post by Robby
*and* when we create an object and
call a function passing a pointer to the object as a parameter.
I don't know of any special name for this technique. It's a function call like any other.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Robby
2010-02-03 23:22:09 UTC
Permalink
Well, if they are compile-time constants, what precisely does it mean >to "manipulate" them?
The values never change once they are set innitially! After that in very
rare cases would a system's frequency have to be altered. But nontheless it
might! So defining them is probably not a good idea.
So, forget about implementation details. Design the interface from the client's >point of view: if you somehow magically had a thrid-party library of your dreams >doing precisely what you want to do, what would that library's API look like? What >calls would you make to it? Then, once you have your ideal interface, fill in the >implementation.
Its just a matter of calculating the values we saw earlier and assigning the
result to CURR_SYS_OSC and making it global..... but there are dozens of
ways to do this.... is it better to call a function and use the macro in
there , like this:

====================================x.h
#define COMPUTE(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))

#define OSC_PERIOD (1.0/CURR_SYS_OSC)

===================================x.c
main()
{ int CURR_SYS_OSC;
CURR_SYS_OSC = compute_sys_osc(8.0, 2.0, 21.0, 8.0);
SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
}

int compute_sys_osc(extCrys, fpllidiv, fpllmul, fpllodiv)
{
int FREQ;

FREQ = COMPUTE(extCrys, fpllidiv, fpllmul, fpllodiv);
return FREQ;
}
==================================

But if I do this, CURR_SYS_OSC is not available to other modules that might
need it.
Also, CURR_SYS_OSC would not be available for the OSC_PERIOD #define
statement. So I think, the above code is not an object oriented approach!
This is *code it* just so that it works!

Another solution would be how I have it now with simple defines:

====================================x.h
#define CURR_SYS_OSC (((float)(8.0/2.0)*(float)(21.0/8.0))*1000000)
#define OSC_PERIOD (1.0/CURR_SYS_OSC)

====================================x.c
int main(void)
{
SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
//... other code
}
======================================

This too is *code it* just so that it works!
Perhaps. It's hard for me to say, as I have no idea what it is you are trying to ? >achieve. Now, before you go and write a long explanation,
Sorry if I come across this way! :-)
note that I'm probably not going to read it: except in very simple and obvious >cases, it takes too much effort to understand the problem well enough to offer a >good design, so as a rule, I don't give design advice.
And that's okay too. I understand.
None. API is just a collection of functions, usually designed to work together and >united by a common theme. An "API call" is just a shorthand for "a call to a >function from some API" (it is usually clear from context which API is meant).
So what you are saying is that this is an API function:

void f1()
{
// does something!
}

Its also possible that API's take in a pointer to an object. And once in the
function, they manipulate the data of that object through the pointer that
was passed in. And that's okay! Having said that, where I get confused is I
may create an object like this:

=========================
typedef struct tag_x
{int z;} x;

void config_obj(struct tag_x y, int a)
{
y.z = a;
}

int main()
{
x y;
config_obj(y,100);
return 0;
}
=========================

now, is config_obj() an API or just a simple function used to innitialize
the values of an object?

Thanks for your time and help!

Rob
Igor Tandetnik
2010-02-04 01:18:27 UTC
Permalink
Post by Robby
So, forget about implementation details. Design the interface from the client's >point of view: if you somehow magically had a
thrid-party library of your dreams >doing precisely what you want to do, what would that library's API look like? What >calls
would you make to it? Then, once you have your ideal interface, fill in the >implementation.
Its just a matter of calculating the values we saw earlier and assigning the
result to CURR_SYS_OSC and making it global..... but there are dozens of
ways to do this.... is it better to call a function and use the macro in
===================================x.c
main()
{ int CURR_SYS_OSC;
CURR_SYS_OSC = compute_sys_osc(8.0, 2.0, 21.0, 8.0);
SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
}
int compute_sys_osc(extCrys, fpllidiv, fpllmul, fpllodiv)
{
int FREQ;
FREQ = COMPUTE(extCrys, fpllidiv, fpllmul, fpllodiv);
return FREQ;
}
==================================
But if I do this, CURR_SYS_OSC is not available to other modules that might
need it.
How about breaking it into two calls:

set_sys_osc(parameters_here);
get_sys_osc();

Have set_sys_osc store the computed value in a file-level static variable, for example, in the source file where these two functions are defined, and get_sys_osc return that variable. No macros needed.
Post by Robby
Also, CURR_SYS_OSC would not be available for the OSC_PERIOD #define
statement. So I think, the above code is not an object oriented approach!
I'm not sure what "object oriented" has to do with this problem. In any case, piling on ever more macros is certainly not the one true way to the OOP nirvana.
Post by Robby
void f1()
{
// does something!
}
If it is part of a collection of related functions, then why not. "API" doesn't mean anything special at the language level - there's no keyword or anything to mark a function as being "API". It's just a way to think about organizing software.
Post by Robby
now, is config_obj() an API or just a simple function used to innitialize
the values of an object?
Again - API is a collection of related functions. It's meaningless to ask whether one isolated function is "an API".
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Robby
2010-02-04 16:32:04 UTC
Permalink
Post by Igor Tandetnik
set_sys_osc(parameters_here);
get_sys_osc();
Have set_sys_osc store the computed value in a file-level static variable, for >example, in the source file where these two functions are defined, and >get_sys_osc return that variable. No macros needed.
Thanks for your guidence Igor. I will probably do that... so your saying, no
structures to keep these 5 variables together, no macros to carry out the
calculations in an orderly fashion.... seems so basic. But hey! I will do
just 2 functions for now.

Thanks for your help and feedback!

Regards
Rob
Igor Tandetnik
2010-02-04 16:56:00 UTC
Permalink
Post by Robby
Post by Igor Tandetnik
set_sys_osc(parameters_here);
get_sys_osc();
Have set_sys_osc store the computed value in a file-level static
variable, for >example, in the source file where these two functions
are defined, and >get_sys_osc return that variable. No macros
needed.
Thanks for your guidence Igor. I will probably do that... so your
saying, no structures to keep these 5 variables together
Well, do you need these five pieces of data separately for some other reason, or do you just need the end result of the calculation? If you just need them once to calculate this sys_osc value, then there's no reason to store them.
Post by Robby
no macros
to carry out the calculations in an orderly fashion
Why have macros when you can use functions?
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Robby
2010-02-04 18:23:02 UTC
Permalink
Well, do you need these five pieces of data separately for some other reason, or >do you just need the end result of the calculation? If you just need them once to >calculate this sys_osc value, then there's no reason to store them.
I need the end result (CURR_SYS_OSC) in main.c and I need the OSC_PERIOD in
another module. But as you can see in innitial post OSC_PERIOD depends on
CURR_SYS_OSC !!! So that's why I would need to store only the 4 values so I
can use OSC_PERIOD in another module. The fifth value is CURR_SYS_OSC, which
I only need in main, but it would be nice if I can store that too cause I
might just need that somewhere else in some othe module.

I am so discouraged beacause I have coded this and everything works but I am
not happy with the way I did it. I would have to show the whole picture of
how it all ties into another module called myLibs.c.

But I don't want to bother you or anyone else for that matter with all of
that. But it would be the only way for me to explain in detail what I really
want and what is going on.

Right now I am trying to store the 4 pieces of information in 4 static
extern variables
so I can calculate the fifth variable which is CURR_SYS_OSC. I started doing
tests to try to just store 2 ints via a macro (I know you said to use
functions... but it bugs me as to why it wouldn't work with a macro) and this
doesn't even work: see here:

==============test.h
#ifndef TEST_H
#define TEST_H
#define Z() ( y = 3; \
a = 4 \ )

extern int y;
extern int a;

#endif //

==========================test.c
include <stdio.h>
#include "test.h"

int y;
int x;

int main()
{ Z();
return 0;
}
===============================

I get the following error:

1>c:\_dts_programming\pic\_microchip_issues\simulated in
vc++\define_macros\define_macros\define_macros\test.h(15) : error C2059:
syntax error : ')'

I tried the define satement as shown in many examples on the Internet, with
curly brackets instead of round, with semie colons, without semie colons,
with back slashes, without back slashes.... and I always get some type of
error. You have to excuse me Igor, I am not that good with define macros that
carry out some code, its all new to me.

Thanks in advance for getting back to me!

Sincere regards
Rob
Igor Tandetnik
2010-02-04 18:35:25 UTC
Permalink
Post by Robby
Post by Igor Tandetnik
Well, do you need these five pieces of data separately for some
other reason, or >do you just need the end result of the
calculation? If you just need them once to >calculate this sys_osc
value, then there's no reason to store them.
I need the end result (CURR_SYS_OSC) in main.c and I need the
OSC_PERIOD in another module. But as you can see in innitial post
OSC_PERIOD depends on CURR_SYS_OSC !!!
So, why not

get_osc_period() {
return 1.0 / get_sys_osc();
}
Post by Robby
==============test.h
#ifndef TEST_H
#define TEST_H
#define Z() ( y = 3; \
a = 4 \ )
You can't enclose statements in parentheses. I mean, the macro doesn't care, it's just a piece of text, but when it's actually expanded and the resulting text compiled, it turns into

(y = 3;
a = 4 )

which doesn't make any sense.

I'm also not sure what that backslash in front of a paren is supposed to do.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Robby
2010-02-04 19:37:02 UTC
Permalink
Post by Igor Tandetnik
Post by Robby
Post by Igor Tandetnik
Well, do you need these five pieces of data separately for some
other reason, or >do you just need the end result of the
calculation? If you just need them once to >calculate this sys_osc
value, then there's no reason to store them.
I need the end result (CURR_SYS_OSC) in main.c and I need the
OSC_PERIOD in another module. But as you can see in innitial post
OSC_PERIOD depends on CURR_SYS_OSC !!!
So, why not
get_osc_period() {
return 1.0 / get_sys_osc();
}
Yes, I will try this. If I run into any problems I will post a new thread
showing the sample with myLib.c module.
Post by Igor Tandetnik
Post by Robby
==============test.h
#ifndef TEST_H
#define TEST_H
#define Z() ( y = 3; \
a = 4 \ )
You can't enclose statements in parentheses. I mean, the macro doesn't care, it's just a piece of text, but when it's actually expanded and the resulting text compiled, it turns into
(y = 3;
a = 4 )
which doesn't make any sense.
I am trying stuff I read in samples.... like for example at:

http://en.wikipedia.org/wiki/C_preprocessor

And so this doesn't work either:
==============test.h
#ifndef TEST_H
#define TEST_H
#define Z(a,b) y = a; \
a = b; \
extern int y;
extern int a;
#endif
==========================test.c
include <stdio.h>
#include "test.h"

int y;
int x;

int main()
{ Z();
return 0;
}
===============================

Regards
Rob
Igor Tandetnik
2010-02-04 19:51:50 UTC
Permalink
Post by Robby
==============test.h
#define Z(a,b) y = a; \
a = b; \
extern int y;
The sequence of assignments looks suspicious. Note that 'a' in both places refers to the macro parameter, not to the variable 'a'.

Also, because of the trailing backslash after "a = b;", the line "extern int y;" is also part of the macro. It doesn't look like you meant that.
Post by Robby
int main()
{ Z();
Z takes two parameters. You are trying to use it with none.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Robby
2010-02-04 20:48:01 UTC
Permalink
Post by Igor Tandetnik
Post by Robby
==============test.h
#define Z(a,b) y = a; \
a = b; \
extern int y;
The sequence of assignments looks suspicious. Note that 'a' in both places refers to the macro parameter, not to the variable 'a'.
Also, because of the trailing backslash after "a = b;", the line "extern int y;" is also part of the macro. It doesn't look like you meant that.
Post by Robby
int main()
{ Z();
Z takes two parameters. You are trying to use it with none.
aaahhhrrhg! clumsy me! That's not what I meant! ooofff! Here you go.

==========test.h
#define Z(a,b) y = a; \
e = b; // << no back slah here to end macro, no ???

extern int y;
extern int e;

============test.c
#include <stdio.h>
#include "test_A.h"
int y;
int e;

int main()
{Z(1,2);
return 0;
}
==============

This still gives errors. But is it even possible to assign a value to the
extern variables while inside a macro? Or am I doing something that can't be
done in C ?

Anyhow I sort of gave on this route, I am more focusing in the two functions
route you pointed out. Please see my last thread.

All help appreciated!

Rob
Igor Tandetnik
2010-02-04 21:37:30 UTC
Permalink
Post by Robby
==========test.h
#define Z(a,b) y = a; \
e = b; // << no back slah here to end macro, no ???
extern int y;
extern int e;
============test.c
#include <stdio.h>
#include "test_A.h"
The header is called test.h, not test_A.h
Post by Robby
int y;
int e;
int main()
{Z(1,2);
return 0;
}
==============
This still gives errors.
What errors?
Post by Robby
But is it even possible to assign a value to
the extern variables while inside a macro?
Macro is just textual substitution. When the macro is used, its body is expanded, parameters substituted, and the result compiled just as if you typed it in directly in place of the macro.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Tamas Demjen
2010-02-04 22:02:12 UTC
Permalink
Post by Robby
==========test.h
#define Z(a,b) y = a; \
e = b; // << no back slah here to end macro, no ???
Backslash immediately followed by a newline means "my macro still
continues".
Post by Robby
This still gives errors.
What errors exactly? It shouldn't. Except that you seem to have a space
and a tab after the backslash. It doesn't work that way. Backslash-
newline is what you want.
Post by Robby
But is it even possible to assign a value to the
extern variables while inside a macro?
There's nothing magical happening inside a macro. It's like cut and
paste. Just select the definition of the macro in your imagination, and
move it into the code where you're using it. That's it.

Z(1,2);

becomes

y = 1;
e = 2;

Note: To be precise, macros work with C tokens, not with characters,
but it's easier for you right now to think of a macro as a cut-and-paste
in your editor. It's close enough.

Tom
Tim Roberts
2010-02-05 07:12:49 UTC
Permalink
Post by Robby
aaahhhrrhg! clumsy me! That's not what I meant! ooofff! Here you go.
==========test.h
#define Z(a,b) y = a; \
e = b; // << no back slah here to end macro, no ???
extern int y;
extern int e;
============test.c
#include <stdio.h>
#include "test_A.h"
int y;
int e;
int main()
{Z(1,2);
return 0;
}
==============
This still gives errors. But is it even possible to assign a value to the
extern variables while inside a macro? Or am I doing something that can't be
done in C ?
Sure, it's possible, but it is an EXTREMELY bad idea. Why? Look at this
statement:
Z(1,2);

From that statement, why would the reader ever suspect that this statement
will be modifying global variables?

As a general rule, preprocessor magic is almost always a bad idea. Macros
are fine for constants and conversions, but anything more complicated than
that is trouble. Use functions instead.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Continue reading on narkive:
Loading...