Discussion:
"PORTING C" > code for CURR_SYS_OSC
(too old to reply)
Robby
2010-02-04 20:15:02 UTC
Permalink
Hello,

Igor, I hope you are still around, I would really like to persue what we
were talking about in the previous thread. I know this seems like we are
going backwards here, but the trouble I am having has more to do on structure
than coding... and ofcourse my lack of experience in C ! :-)

I hope all this will lead up to what I am looking for. Sometimes I have a
hard time putting this stuff into words.

Okay, I like your proposition of the two functions. So let me start with
that. There is a first problem that I am running into. I did the two
functions. The first one called set_curr_sys_osc() and the second one called
get_curr_sys_osc(). Here is what I did so far, I will try to keep it short:

=============================test.h
#ifndef TEST_H
#define TEST_H

#define COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

extern static float the_sys_osc; //< store the SYS_CURR_OSC value here!
#endif // TEST_H //

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

// In exactly one .c file.
static float the_sys_osc=0;

void set_curr_sys_osc(float extCrys, float fpllidiv, float fpllmul, float
fpllodiv)
{
the_sys_osc = COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv);
}

int get_curr_sys_osc()
{
return (int) the_sys_osc;
}

int main()
{
set_curr_sys_osc(8.0, 2.0, 21.0, 8.0);

// >>> SYSTEMConfig() is not one of my functions!
//SYSTEMConfig((int)get_curr_sys_osc(), SYS_CFG_ALL);

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

The above code generates the following error:

1>c:\_dts_programming\pic\_microchip_issues\simulated in
vc++\define_macros\define_macros\define_macros\test.h(13) : error C2159: more
than one storage class specified

It seems to point to the extern value I created. I did this extern variable
like all the others.... meaning:

- declaring it in the header file
- innitializing it in exactly one .c file
- using it in a function of test.c

Why the error?

Please get back!
--
Sincere regards
Roberto
Igor Tandetnik
2010-02-04 20:25:31 UTC
Permalink
Post by Robby
Okay, I like your proposition of the two functions. So let me start
with that. There is a first problem that I am running into. I did the
two functions. The first one called set_curr_sys_osc() and the second
one called get_curr_sys_osc(). Here is what I did so far, I will try
=============================test.h
#ifndef TEST_H
#define TEST_H
#define COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
Why do you want this macro in the header file? Are users of this module expected to use it? In fact, it's not clear to me why you need this macro in the first place.

On the other hand, you are talking about the two functions - but you didn't place _their_ declarations into the header. How are clients supposed to call them?
Post by Robby
extern static float the_sys_osc; //< store the SYS_CURR_OSC value
here! #endif // TEST_H //
There ain't no such thing as "extern static". The two qualifiers have precisely opposite meaning are cannot be combined.

The variable is an internal implementation detail, it shouldn't be in the header.
Post by Robby
=================================test.c
#include <stdio.h>
#include "test.h"
// In exactly one .c file.
static float the_sys_osc=0;
void set_curr_sys_osc(float extCrys, float fpllidiv, float fpllmul,
float fpllodiv)
{
the_sys_osc = COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv);
}
int get_curr_sys_osc()
{
return (int) the_sys_osc;
Why do you store the value as float when you always cast it to int anyway?
Post by Robby
}
int main()
{
set_curr_sys_osc(8.0, 2.0, 21.0, 8.0);
// >>> SYSTEMConfig() is not one of my functions!
//SYSTEMConfig((int)get_curr_sys_osc(), SYS_CFG_ALL);
get_curr_sys_osc already returns int, no need to cast.
Post by Robby
1>c:\_dts_programming\pic\_microchip_issues\simulated in
vc++\define_macros\define_macros\define_macros\test.h(13) : error
C2159: more than one storage class specified
Like I said, no such thing as "extern static".
--
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 22:28:01 UTC
Permalink
Igor, you have done it again,

You have inspired me to persist on a resolution you provided and I finally
got it to work. I really, really want to thank you very much.
Why do you want this macro in the header file? Are users of this module expected >to use it?
Hum, these the questions I am not too clear about yet. But I don't know yet
if users of this module will need to use it... I mean now that we have done
the three functions... its not clear to me either. Perhaps, one might need to
re-compute the current system oscilation value from the macro _again_ !!!
In fact, it's not clear to me why you need this macro in the first place.
Yeah your right, but I use it in one of the functions, and I need practice
with these macros. I know, its a cheap excuse. :-)
There ain't no such thing as "extern static". The two qualifiers have precisely >opposite meaning are cannot be combined.
Understood. I fixed it.

In any case Igor, I don't know if what I have done can be improved... by
your or this forum's standars, I suppose so, but I am quite happy with what
I have done. It all runs perfectly in MPLAB, so I haven't tried it in VC but
it does compile without error. So all I did was copy and paste from MPLAB IDE
to VC IDE. Here you can see why sometimes things are hard for me to explain
because I am thinking of everything else that goes on at the same time.
Please view what I have done, and if there is any other recomendations (I am
sure you will have!!!) let me know. But as I say, you have very much helped
me a great deal and I am happy with this so far.

The idea was to store the system frequency clock in a variable and then use
that variable to calculate a precise delay time in milli-seconds or
micro-seconds by simply calling a delay function on the fly. Even though
there are better ways to do delays, when bit banging at very short delays,
calling a delay function on the fly is very convinient. I have created 2 of
these delay functions, one for milli-seconds and another for micro-seconds.
Now, even if I decide to speed up the processor, these delay functions will
take into account all the overhead instructions and still carry out the
correct delays.

Here is the code:

========================KERNEL.h
#ifndef KERNEL_H
#define KERNEL_H

#define COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

extern float curr_sys_osc;

void set_curr_sys_osc(float extCrys, float fpllidiv, float fpllmul, float
fpllodiv);
int get_curr_sys_osc();
float get_osc_period();

#endif // KERNEL_H //

=========================KERNEL.c
#include <stdio.h>
#include "KERNEL.h"
#include "MYLIB.h"

// In exactly one .c file.
static float curr_sys_osc=0;

void set_curr_sys_osc(float extCrys, float fpllidiv, float fpllmul, float
fpllodiv)
{curr_sys_osc = COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv);}

int get_curr_sys_osc()
{return (int) curr_sys_osc;}

float get_osc_period()
{return (1/curr_sys_osc);}

int main()
{
set_curr_sys_osc(8.0, 2.0, 21.0, 8.0);
SYSTEMConfig(get_curr_sys_osc(), SYS_CFG_ALL); // Config wait states

// do something...

// Now I can call a delay routine on the fly
// no matter what I set my system frequency to.
delay_us(100);

// other code....
return 0;
}

=========================MYLIB.h
#ifndef MYLIB_H
#define MYLIB_H

#include "KERNEL.h"

// MILLI-SECOND DELAY FUNCTION @ optimization :0:
#define MILLI_SEC 0.001

// MICRO-SECOND DELAY FUNCTION @ optimization :0:
#define MICRO_SEC 0.000001

// INSTRUCTION CYCLES REQUIRED FOR DELAY FUNCTIONS @ optimization :0:
#define OVERHEAD_IC 67 // 67 overhead instructions
#define DELAY_LOOP_IC 8.0 // Instructions in the delay loop + ext # brch
in loop
#define LOOPS_REMOVE(a,b) (a/b) // Calculates dleay loops to remove
#define RATIO(a,b,c) (a/(b*c)) // Figures out ratio to apply to scale freq

void delay_ms(unsigned int ms_delay);
void delay_us(unsigned int us_delay);

#endif //MYLIB_H

===============================MYLIB.c
#include "MYLIB.h"

void delay_us(unsigned int us_delay)
{
unsigned int t;
float x,y;

x = ((float)RATIO((float)MICRO_SEC, get_osc_period(), (float)DELAY_LOOP_IC))
* (float)us_delay; //Ratio constant @ x-MHZ!

// Test if < shortest time possible !
if(x < (LOOPS_REMOVE((float)OVERHEAD_IC, (float)DELAY_LOOP_IC)))
t = 1; // Sys Osc is too slow... apply minimum delay!
else
{
// Get number of while loops to remove
y = (float) LOOPS_REMOVE((float)OVERHEAD_IC, (float)DELAY_LOOP_IC);

// Remove amount of while loops to compensate by time lost by overhead
//instructions
t = (int)(x-y);
}

while(--t) // do the delay!
{}
}


void delay_ms(unsigned int ms_delay)
{
unsigned int t;
float x,y;

x = ((float)RATIO((float)MILLI_SEC, get_osc_period(), (float)DELAY_LOOP_IC))
* (float)ms_delay;

// Test if < shortest time possible !
if(x < (LOOPS_REMOVE((float)OVERHEAD_IC, (float)DELAY_LOOP_IC)))
t = 1; // Sys Osc is too slow... apply minimum delay!
else
{
// Get number of while loops to remove
y = (float) LOOPS_REMOVE((float)OVERHEAD_IC, (float)DELAY_LOOP_IC);

// Remove amount of while loops to compensate by time lost by overhead
// instructions
t = (int)(x-y);
}

while(--t) // do the delay!
{}
}

=========================================

I am sure that more can be done to improve the MYLIB.c/.h module. But for
now, I will leave it like this.

Igor, I thank you for your insight, advice and most imporatant, your
constant assistance you give me time after time.

Sincere regards
Roberto
Ulrich Eckhardt
2010-02-05 08:07:49 UTC
Permalink
Post by Robby
#define COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
Why? Why isn't this a function?
Post by Robby
extern float curr_sys_osc;
This says: There is a global variable for anyone to access. However, zero
documentation on how to use it...
Post by Robby
void set_curr_sys_osc(float extCrys, float fpllidiv,
float fpllmul, float fpllodiv);
int get_curr_sys_osc();
float get_osc_period();
All these seem to have something to do with the above global variable.
Post by Robby
// In exactly one .c file.
static float curr_sys_osc=0;
This says: Create a variable accessible _only_ in this file. This conflicts
with the declaration in the header.
Post by Robby
void set_curr_sys_osc(float extCrys, float fpllidiv, float fpllmul, float
fpllodiv)
{curr_sys_osc = COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv);}
The macro is used here, where else? I guess nowhere, so move it into this
source file. Further, since even here it seems to only be used once, so you
don't need it at all. Macro are a simple text substitution mechanism
without any type checking. Adding all the casts you have in there, you get
zero checking. This is a recipe for disaster and bad programming.
Post by Robby
int get_curr_sys_osc()
{return (int) curr_sys_osc;}
float get_osc_period()
{return (1/curr_sys_osc);}
Why not get_curr_sys_osc_period()? Why not get_curr_sys_osc_frequency()?
Also, these in combination with set_curr_sys_osc() show that curr_sys_osc
should not be global and visible everywhere.

Mylib.c/h are the same, too many global macros, too much type casting.

Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Robby
2010-02-05 17:19:01 UTC
Permalink
Post by Ulrich Eckhardt
Post by Robby
#define COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
Why? Why isn't this a function?
Hello Uli,

I don't know why I didn't make it a function. But why shouldn't it be a
macro?
Post by Ulrich Eckhardt
Post by Robby
extern float curr_sys_osc;
This says: There is a global variable for anyone to access. However, zero
documentation on how to use it...
So your saying I should add coments!
Post by Ulrich Eckhardt
Post by Robby
void set_curr_sys_osc(float extCrys, float fpllidiv,
float fpllmul, float fpllodiv);
int get_curr_sys_osc();
float get_osc_period();
All these seem to have something to do with the above global variable.
Yes.
Post by Ulrich Eckhardt
Post by Robby
// In exactly one .c file.
static float curr_sys_osc=0;
This says: Create a variable accessible _only_ in this file. This conflicts
with the declaration in the header.
Thats the way we do globals... no?

- extern a var in a header file
- In exactly one .c file define or declare the var for that .c file
- and include the header file where the var is externed for every other .c
file that wishes to use the var !!! (I could be wrong! but its what I posted
and discussed about this a month or so)
Post by Ulrich Eckhardt
Post by Robby
void set_curr_sys_osc(float extCrys, float fpllidiv, float fpllmul, float
fpllodiv)
{curr_sys_osc = COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv);}
The macro is used here, where else? I guess nowhere, so move it into this
source file. Further, since even here it seems to only be used once, so you
don't need it at all. Macro are a simple text substitution mechanism
without any type checking. Adding all the casts you have in there, you get
zero checking. This is a recipe for disaster and bad programming.
It might be used else where in the future. But what type of "type checking"
do you mean I should do in this function... Can you give me an example.
Thankyou!
Post by Ulrich Eckhardt
Post by Robby
int get_curr_sys_osc()
{return (int) curr_sys_osc;}
float get_osc_period()
{return (1/curr_sys_osc);}
Why not get_curr_sys_osc_period()? Why not get_curr_sys_osc_frequency()?
Also, these in combination with set_curr_sys_osc() show that curr_sys_osc
should not be global and visible everywhere.
I will need these for other modules. This sample is a far cry from the
project's actual size.
Post by Ulrich Eckhardt
Mylib.c/h are the same, too many global macros, too much type casting.
Yes, I thought so too. But right now, I have one priority... complete the
port. I did this as an extra to quickly organize things the best I could for
the frequency adaption for the delay function since in the new compiler
doesn't provide these.

Regards
Rob
David Wilkinson
2010-02-05 19:07:19 UTC
Permalink
Post by Robby
Post by Ulrich Eckhardt
Post by Robby
// In exactly one .c file.
static float curr_sys_osc=0;
This says: Create a variable accessible _only_ in this file. This conflicts
with the declaration in the header.
Thats the way we do globals... no?
- extern a var in a header file
- In exactly one .c file define or declare the var for that .c file
- and include the header file where the var is externed for every other .c
file that wishes to use the var !!! (I could be wrong! but its what I posted
and discussed about this a month or so)
Yes, but not with the static keyword!
--
David Wilkinson
Visual C++ MVP
Robby
2010-02-05 21:51:02 UTC
Permalink
Hi David,
Post by David Wilkinson
Post by Robby
Post by Ulrich Eckhardt
Post by Robby
// In exactly one .c file.
static float curr_sys_osc=0;
This says: Create a variable accessible _only_ in this file. This conflicts
with the declaration in the header.
Thats the way we do globals... no?
- extern a var in a header file
- In exactly one .c file define or declare the var for that .c file
- and include the header file where the var is externed for every other .c
file that wishes to use the var !!! (I could be wrong! but its what I posted
and discussed about this a month or so)
Yes, but not with the static keyword!
So, in C, we *can't* have global static variables. I guess it would make
sence though. If a variable is global, why would it need to be static. Its
global! Its contents will never be lost!!!

So I take it as we can't do global static variables in C.

Regards
Rob
Tamas Demjen
2010-02-05 23:39:41 UTC
Permalink
Post by Robby
So, in C, we *can't* have global static variables. I guess it would make
sence though. If a variable is global, why would it need to be static. Its
global! Its contents will never be lost!!!
I think you're mixing the terminology. The static keyword is context
sensitive, and depending on where it appears, it has a completely
different meaning. Declaring a variable in the global scope has nothing
to do with it being static or not.

Variables have a lifetime (duration) and a visibility, and those
concepts are more or less independent.

The global scope means you're not inside a function, structure, or
union. In simple terms, you're not inside a curly brace. Variables
in the global scope have the same lifetime as the application.
They never go out of scope, so they never lose their values.
Variables inside a function normally lose their values when the
function exits, unless they're declared static.

Visibility can be different than lifetime. A variable can be visible
inside a scope, in an entire .c file, or inside the entire executable.
In case of a DLL/shared object/dylib, you can also control whether a
variable or function is exported (available to the client of the
library).

Let's see an example for global and local scope:

// main.c
#include <stdio.h>

int global_scope;
// lifetime: global (until the app exits)
// visibility: global (for the entire executable/module)

void f()
{
int local_scope;
// lifetime: local (till the function exits)
// visibility: local (for this function only)
}

If you use the static keyword in the global scope, it means the variable
or function is only accessible in the translation unit where it's
declared:

static int internal_global;
// lifetime: global (until the app exits)
// visibility: local (for this .c unit only)

It's in the global scope, so it has a global life span, but it's local
in terms of accessibility. You can't refer to it from the outside.
static means it can't be extern, and other .c translation units can't
see it. You can define another internal_global variable in another .c
file without conflict.

The static keyword has a completely different meaning when used inside
a function:

int f()
{
static int call_counter = 0;
// lifetime: global (until the app exits)
// visibility: local (for this function only)
++call_counter;
}

This means the variable keeps its value in between function calls, but
it still remains private to the f() function. You can't possibly access
call_counter outside of f(), but due to its static nature, the variable
stays alive, even when the function returns.

Functions can also be declared static. Functions have visibility only,
no lifetime, so static only controls whether a function is hidden inside
a .c file, or visible across the entire project.

In C++ the static keyword has a whole bunch of other meanings.
A static member means it belongs to the class, not to the instance.
As you see, the static keyword is always interpreted
differently, depending on the context in which it appears.

Tom
Robby
2010-02-08 22:58:05 UTC
Permalink
Post by Tamas Demjen
Post by Robby
So, in C, we *can't* have global static variables. I guess it would make
sence though. If a variable is global, why would it need to be static. Its
global! Its contents will never be lost!!!
I think you're mixing the terminology. The static keyword is context
sensitive, and depending on where it appears, it has a completely
different meaning. Declaring a variable in the global scope has nothing
to do with it being static or not.
Variables have a lifetime (duration) and a visibility, and those
concepts are more or less independent.
The global scope means you're not inside a function, structure, or
union. In simple terms, you're not inside a curly brace. Variables
in the global scope have the same lifetime as the application.
They never go out of scope, so they never lose their values.
Variables inside a function normally lose their values when the
function exits, unless they're declared static.
Visibility can be different than lifetime. A variable can be visible
inside a scope, in an entire .c file, or inside the entire executable.
In case of a DLL/shared object/dylib, you can also control whether a
variable or function is exported (available to the client of the
library).
// main.c
#include <stdio.h>
int global_scope;
// lifetime: global (until the app exits)
// visibility: global (for the entire executable/module)
void f()
{
int local_scope;
// lifetime: local (till the function exits)
// visibility: local (for this function only)
}
If you use the static keyword in the global scope, it means the variable
or function is only accessible in the translation unit where it's
static int internal_global;
// lifetime: global (until the app exits)
// visibility: local (for this .c unit only)
It's in the global scope, so it has a global life span, but it's local
in terms of accessibility. You can't refer to it from the outside.
static means it can't be extern, and other .c translation units can't
see it. You can define another internal_global variable in another .c
file without conflict.
The static keyword has a completely different meaning when used inside
int f()
{
static int call_counter = 0;
// lifetime: global (until the app exits)
// visibility: local (for this function only)
++call_counter;
}
This means the variable keeps its value in between function calls, but
it still remains private to the f() function. You can't possibly access
call_counter outside of f(), but due to its static nature, the variable
stays alive, even when the function returns.
Functions can also be declared static. Functions have visibility only,
no lifetime, so static only controls whether a function is hidden inside
a .c file, or visible across the entire project.
In C++ the static keyword has a whole bunch of other meanings.
A static member means it belongs to the class, not to the instance.
As you see, the static keyword is always interpreted
differently, depending on the context in which it appears.
This is valuable information for me since this wasn't exactly the case in
the old non C compliant compiler. Thanks Tom!

Robert
Igor Tandetnik
2010-02-05 20:55:12 UTC
Permalink
Post by Robby
Post by Ulrich Eckhardt
Post by Robby
#define COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
Why? Why isn't this a function?
I don't know why I didn't make it a function. But why shouldn't it be
a macro?
The right question to ask is - does it absolutely have to be a macro? If you can manage without, don't use macros. See also

http://www.gotw.ca/gotw/063.htm
--
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-05 22:09:01 UTC
Permalink
Post by Igor Tandetnik
Post by Robby
Post by Ulrich Eckhardt
Post by Robby
#define COMPUTE_SYS_OSC(extCrys, fpllidiv, fpllmul, fpllodiv) \
(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
Why? Why isn't this a function?
I don't know why I didn't make it a function. But why shouldn't it be
a macro?
The right question to ask is - does it absolutely have to be a macro? If you can manage without, don't use macros.
I probably doesn't really have to be a macro.

I don't know about you guys, but the way I see the usefulness of macros
would be lets say we are doing a function, and all of the sudden we need to
do a calculation of some sort. Not to clutter up the code in the function, I
would use a macro... its clean out of the way and does one and only one
particular thing. Okay, now I have breifed the article and I see that macros
are a don't care text substitution operation in your code and so on.... but
so far I never had these problems. And what would we care if the compiler
changes our macro name from sleep() to sleepEX(). Isn't all this transparent
to the programmer?

Regards
Robert
Igor Tandetnik
2010-02-05 22:15:58 UTC
Permalink
Post by Robby
I don't know about you guys, but the way I see the usefulness of
macros would be lets say we are doing a function, and all of the
sudden we need to do a calculation of some sort. Not to clutter up
the code in the function, I would use a macro...
Why not another function? It's not like you are being charged per function used.
--
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-06 00:12:01 UTC
Permalink
Post by Igor Tandetnik
Post by Robby
I don't know about you guys, but the way I see the usefulness of
macros would be lets say we are doing a function, and all of the
sudden we need to do a calculation of some sort. Not to clutter up
the code in the function, I would use a macro...
Why not another function? It's not like you are being charged per function used.
Hi Igor,

No, no, no, I have a bigger processor now, with lots and lots of memory and
I could do as many functions as I want and that's without being charged. :-)

But just to reminisse here, so then lets do everything with functions. Why
bother with macros at all. Why even keep macros in the C language standard.
You read the article yourself, were supposed to say yuuuk! when we hear the
word "macro".

Also, I *think* having an important calculation such as the system frequency
calculation, would be a calculation deemed important to be set up there for
it to be globally defined as a macro. I might need this calculation on the
fly without going through a bunch of functions to find the one function that
does this very specific calculation. Anyway its just my *personal* opinion.

The important thing is that a group of C commands carry out logic that works
no matter if its done by a function or a macro. Maybe macros are not as safe
as functions but they do great when its for one *very* particular
calculation...
I guess! :-)

And I agree with you in a sence... I am not too crazy about doing long
macros either, a function is much more practicle.

Oh and by the way Uli, I did remove the conflicting gloabal variable you
were talking about. I only kept the one in the module for module scope. You
were right!

Thank you all for your help. Very appreciated!

Regards
Rob
Bo Persson
2010-02-06 11:35:00 UTC
Permalink
Post by Robby
Post by Igor Tandetnik
Post by Robby
I don't know about you guys, but the way I see the usefulness of
macros would be lets say we are doing a function, and all of the
sudden we need to do a calculation of some sort. Not to clutter up
the code in the function, I would use a macro...
Why not another function? It's not like you are being charged per function used.
Hi Igor,
No, no, no, I have a bigger processor now, with lots and lots of
memory and I could do as many functions as I want and that's
without being charged. :-)
It isn't that macros are any faster or smaller than functions, either.
You are not saving anything!

The article is about C++, which added const and inline to do most of
what macros do, but whithout resorting to simple text substitutions.
Now that C has also gotten these improved features, why not use them?
Post by Robby
But just to reminisse here, so then lets do everything with
functions. Why bother with macros at all. Why even keep macros in
the C language standard. You read the article yourself, were
supposed to say yuuuk! when we hear the word "macro".
Macros are useful for include guards, and an occational #ifdef ABC.
The main reason for keeping them is of course that there are lots of
existing code that uses them. But there is not much reason for writing
new code using the old features.
Post by Robby
Also, I *think* having an important calculation such as the system
frequency calculation, would be a calculation deemed important to
be set up there for it to be globally defined as a macro. I might
need this calculation on the fly without going through a bunch of
functions to find the one function that does this very specific
calculation. Anyway its just my *personal* opinion.
So you can have a global constant:

const int x = ;
const float y = ;

These will not magically replace every use of x and y in your program.
Post by Robby
The important thing is that a group of C commands carry out logic
that works no matter if its done by a function or a macro. Maybe
macros are not as safe as functions but they do great when its for
one *very* particular calculation...
I guess! :-)
The article showed that by including a header (like windows.h) before
your header, the function names in YOUR header will be randomly
replaced by other names, like Sleep becoming SleepEx.

If you then don't include the same headers in your .cpp file, you will
get a link time error. How bad is that?!


Bo Persson
Robby
2010-02-06 19:29:01 UTC
Permalink
Post by Bo Persson
Post by Robby
Post by Igor Tandetnik
Post by Robby
I don't know about you guys, but the way I see the usefulness of
macros would be lets say we are doing a function, and all of the
sudden we need to do a calculation of some sort. Not to clutter up
the code in the function, I would use a macro...
Why not another function? It's not like you are being charged per function used.
Hi Igor,
No, no, no, I have a bigger processor now, with lots and lots of
memory and I could do as many functions as I want and that's
without being charged. :-)
It isn't that macros are any faster or smaller than functions, either.
You are not saving anything!
The article is about C++, which added const and inline to do most of
what macros do, but whithout resorting to simple text substitutions.
Now that C has also gotten these improved features, why not use them?
Post by Robby
But just to reminisse here, so then lets do everything with
functions. Why bother with macros at all. Why even keep macros in
the C language standard. You read the article yourself, were
supposed to say yuuuk! when we hear the word "macro".
Macros are useful for include guards, and an occational #ifdef ABC.
The main reason for keeping them is of course that there are lots of
existing code that uses them. But there is not much reason for writing
new code using the old features.
Post by Robby
Also, I *think* having an important calculation such as the system
frequency calculation, would be a calculation deemed important to
be set up there for it to be globally defined as a macro. I might
need this calculation on the fly without going through a bunch of
functions to find the one function that does this very specific
calculation. Anyway its just my *personal* opinion.
const int x = ;
const float y = ;
These will not magically replace every use of x and y in your program.
Post by Robby
The important thing is that a group of C commands carry out logic
that works no matter if its done by a function or a macro. Maybe
macros are not as safe as functions but they do great when its for
one *very* particular calculation...
I guess! :-)
The article showed that by including a header (like windows.h) before
your header, the function names in YOUR header will be randomly
replaced by other names, like Sleep becoming SleepEx.
If you then don't include the same headers in your .cpp file, you will
get a link time error. How bad is that?!
That is bad!

Very interesting!

Thanks for your insight BO!

Regards
Rob
Tim Roberts
2010-02-07 19:13:15 UTC
Permalink
Post by Robby
But just to reminisse here, so then lets do everything with functions. Why
bother with macros at all. Why even keep macros in the C language standard.
Yes, indeed. MANY people have asked that exact question, including Bjarne
Stroustroup, the guy who created C++. He wanted to get rid of the
preprocessor altogether. Templates and "const" variables are both attempts
to eliminate misused preprocessor features.
Post by Robby
Also, I *think* having an important calculation such as the system frequency
calculation, would be a calculation deemed important to be set up there for
it to be globally defined as a macro. I might need this calculation on the
fly without going through a bunch of functions to find the one function that
does this very specific calculation. Anyway its just my *personal* opinion.
I don't see the difference between "going through a bunch of functions to
find the one" and "going through a bunch of macros to find the one". The
search process is the same, and the function choice is safer.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Robby
2010-02-08 23:11:02 UTC
Permalink
Post by Tim Roberts
Post by Robby
But just to reminisse here, so then lets do everything with functions. Why
bother with macros at all. Why even keep macros in the C language standard.
Yes, indeed. MANY people have asked that exact question, including Bjarne
Stroustroup, the guy who created C++. He wanted to get rid of the
preprocessor altogether.
Interesting!
Post by Tim Roberts
Templates and "const" variables are both attempts to eliminate misused >preprocessor features.
and inline functions too, right?
Post by Tim Roberts
I don't see the difference between "going through a bunch of functions to
find the one" and "going through a bunch of macros to find the one". The
search process is the same, and the function choice is safer.
I never said a *bunch* of macros, since I too tend to limit their use...
especially with all the macro bashing that's been going on :-). A few, (15-20)
macros that carry out simple tasks of a very general settings or calcs
involving the *system's* setups for peripherals or so, I wouldn't mind ! So
this way I would know, if its something to do with a simple system's setup, I
would look into the macros. But then again, as Igor says, why wouldn't I use
functions.

Thanks for your post Tim.

Regards
Rob

Robby
2010-02-04 21:03:01 UTC
Permalink
Post by Robby
1>c:\_dts_programming\pic\_microchip_issues\simulated in
vc++\define_macros\define_macros\define_macros\test.h(13) : error C2159: more
than one storage class specified
It seems to point to the extern value I created. I did this extern variable
- declaring it in the header file
- innitializing it in exactly one .c file
- using it in a function of test.c
Why the error?
I got it to work, I had to change:

extern static float the_sys_osc;

to

extern float the_sys_osc;

I will continue with the two functions resolution and post back if there is
problems.
Please watch this thread. Thanks!

Rob
Loading...