Author Topic: [AVR GCC] Error called object is not a function or function pointer  (Read 12187 times)

0 Members and 1 Guest are viewing this topic.

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Just starting to play with some code and the below line gets me: Error called object is not a function or function pointer.

Code: [Select]
#define TCB0_CLKSEL_CLK_PER      TCB0.CTRLA = ((TCB0.CTRLA & 0b11111001) | 0b00000000) // use peripheral clock.

 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #1 on: August 20, 2018, 08:20:16 pm »
ok, turns out it was caused by a lack of a colon on a similar statement on a different register several lines before. Hm, that's shit! an error in one place throws up an error sowhere else totally unrelated or maybe not as my error was on TCB0.CTRLA and both registers appear to be struct variables in the same group :palm:
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21658
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #2 on: August 20, 2018, 08:29:32 pm »


Also,



Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 
The following users thanked this post: Naguissa

Offline PhilipPeake

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #3 on: August 20, 2018, 08:40:30 pm »
That is what using preprocessor macro functions wins you. :-)
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #4 on: August 20, 2018, 08:57:39 pm »
That is what using preprocessor macro functions wins you. :-)

Not really. Had i used the raw math and forgotten the colon on the same statement it would have thrown an error on the same other statement!

All the define did was tell me what the heck i was doing and hiding the meaningless gibberish that will be copy and pasted in at compile time.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #5 on: August 20, 2018, 09:12:28 pm »
"| 0b00000000"? ok thats charming...
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 
The following users thanked this post: nugglix

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #6 on: August 20, 2018, 09:50:43 pm »
Code: [Select]
#define TCB0_CLKSEL_CLK_PER      TCB0.CTRLA = ((TCB0.CTRLA & 0b11111001) | 0b00000000) // use peripheral clock.
Yuck!

1. Most people avoid putting comments "in" macro definitions
2. "| 0b00000000" ... why? (already mentioned by Mechatrommer)
3. You're defining an "object-like" macro there, but it's got an assignment in it? Dangerous!
4. Why isn't "0b11111001" a named constant?
5. A more readable name for the macro would be helpful. What does "_CLK_PER" mean?
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3140
  • Country: ca
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #7 on: August 20, 2018, 09:57:27 pm »
1. Most people avoid putting comments "in" macro definitions

The compiler strips out comments before processing macros. Thus it doesn't matter where you put the comments.
 
The following users thanked this post: newbrain

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #8 on: August 21, 2018, 06:11:33 am »
Code: [Select]
#define TCB0_CLKSEL_CLK_PER      TCB0.CTRLA = ((TCB0.CTRLA & 0b11111001) | 0b00000000) // use peripheral clock.
Yuck!

1. Most people avoid putting comments "in" macro definitions
2. "| 0b00000000" ... why? (already mentioned by Mechatrommer)
3. You're defining an "object-like" macro there, but it's got an assignment in it? Dangerous!
4. Why isn't "0b11111001" a named constant?
5. A more readable name for the macro would be helpful. What does "_CLK_PER" mean?

1. Why?! comments are throw away text and useful in any code.
2. Yes it is pointless in this statement but this is the first line in a series of statements where that operation changes number, it's simply a template:

// CNTMODE[2:0] Timer Mode Writing these bits selects the Timer mode
#define TCB0_MODE_PERIODIC_INTERRUPT  TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000000)
#define TCB0_MODE_TIME_OUT_CHECK      TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000001)
#define TCB0_MODE_EVENT               TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000010)
#define TCB0_MODE_FREQ_MEASUREMENT    TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000011)
#define TCB0_MODE_PW_MEASUREMENT      TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000100)
#define TCB0_MODE_FREQ_PW_MEASUREMENT TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000101)
#define TCB0_MODE_SINGLE_SHOT         TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000110)
#define TCB0_MODE_8BIT_PWM            TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000111)

4. A named constant. OK if I name one I have to name them all, that is 2^8 permutations........ why does it need naming and further obfuscating? at some point register bits need setting to 0 and 1. Do you make up constants for this stuff when you put such code inline in your main program? making it a constant technically requires an additional .c file.
5. "CLK_PER is THE name of the periphery clock in the datasheet, I can't think of a better name myself.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #9 on: August 21, 2018, 07:13:55 am »
1. Most people avoid putting comments "in" macro definitions
The compiler strips out comments before processing macros. Thus it doesn't matter where you put the comments.
agree, and it helps readability. when we know it doesnt impact the generated code negatively, and on the other side it can give positive impact, we'll do it.

4. A named constant. OK if I name one I have to name them all, that is 2^8 permutations........
you dont have to. only name what are "useful". when you see people try to define all the permutations, then he got an off the chart intelligence :bullshit:

why does it need naming and further obfuscating?
readability. one may think its for the purpose of others, but its not just for others, its also for the programmer himself (you) few months or years from now.

one may think why the heck is "| 0b00000000"? when in fact there is something in your mind, only you know it, hence not readable to others. and in few years when you have forgotten it, it will not be readable to you as well. btw, i did occasionally this kind of charming code because sometime i hate to see one line of code is shorter than the other, so adding a meaningless code may add to the "charmingness", but some people wont give a rat ass and further obfuscated his mind.

now i dont know whats going on in your code (semantically), but for readability sake may i suggest...
Code: [Select]
#define INTR_BIT 0b00000000
#define INTR_MSK 0b11111000

#define CHCK_BIT 0b00000001
#define CHCK_MSK 0b11111000

#define EVNT_BIT 0b00000010
#define EVNT_MSK 0b11111000

...

#define TCB0_MODE_PERIODIC_INTERRUPT  TCB0.CTRLB = ((TCB0.CTRLB & INTR_MSK) | INTR_BIT)
#define TCB0_MODE_TIME_OUT_CHECK      TCB0.CTRLB = ((TCB0.CTRLB & CHCK_MSK) | CHCK_BIT)
#define TCB0_MODE_EVENT               TCB0.CTRLB = ((TCB0.CTRLB & EVNT_MSK) | EVNT_BIT)

...

few things to note...

1) there are few duplicate define (*_MSK), some one may argue what the fuck, why dont just declare it once and use in all? well as you said, they have certain purpose and meaning. being none duplicated is not the point, readability is. and in the future, the value may change, so you only change the define, you dont have to touch the rest.
2) i dont put parenthesis in the define because its a simple number, i imagine there's very little (from experience) can go wrong with that. if you want extra taboo, you can put parenthesis, it may help a "good practice" habit, it wont sacrifice readability imho.

Code: [Select]
#define INTR_BIT (0b00000000)

3) i put some cryptic shortcut such as CHCK instead of CHECK, MSK instead of MASK, because i'm one of the charming coder ;D its good when everything are line up nicely (same character count as the next lines) but sometime it will put us in hard decision because readability is sacrificed, so the charmingness is sometime not advisable. but when we think other reader can assume the meaning correctly, we tend to do so, like in whatsapp texting, we know (or hope) that everybody will know what a INTR means, dont you? ;D further we usually and keep seeing super extra space separators placed in the code just to line up above and bottom code in many places and coders, just as in your example, its not so obvious if you dont put it in code quotation (thats why coders have been using and will always be using i suspect, archaic font such as courier or lucida (fixed width font) instead of times new roman or arial) so i believe i'm not the only charming coder here. but if we go too far, or meaningless without comment or explanation, it can go problematic.

fwiw...
« Last Edit: August 21, 2018, 07:29:03 am by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #10 on: August 21, 2018, 07:27:25 am »
If I had a dollar for every time I've fixed someones code simply by moving the // comment in a #define to the line before.

One of my rules for writing portable code is never put a comment on the same line as a #define. True, it won't bite you 99.9% of the time, but finding those 0.1% problems makes up for it!
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #11 on: August 21, 2018, 07:42:00 am »
inline comment wont even pass the compiler gate. try:
Code: [Select]
#define MYNUM 10 // my number

void main() {
    int i  = MYNUM + 1;
};

it wont hurt and value is just correct, at least to the compilers i'm using here. its not like it will get expanded to...

Code: [Select]
    int i  = 10 // my number + 1;
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #12 on: August 21, 2018, 07:55:03 am »
1. Why?! comments are throw away text and useful in any code.
2. Yes it is pointless in this statement but this is the first line in a series of statements where that operation changes number, it's simply a template:
Code: [Select]
// CNTMODE[2:0] Timer Mode Writing these bits selects the Timer mode
#define TCB0_MODE_PERIODIC_INTERRUPT  TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000000)
#define TCB0_MODE_TIME_OUT_CHECK      TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000001)
#define TCB0_MODE_EVENT               TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000010)
#define TCB0_MODE_FREQ_MEASUREMENT    TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000011)
#define TCB0_MODE_PW_MEASUREMENT      TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000100)
#define TCB0_MODE_FREQ_PW_MEASUREMENT TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000101)
#define TCB0_MODE_SINGLE_SHOT         TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000110)
#define TCB0_MODE_8BIT_PWM            TCB0.CTRLB = ((TCB0.CTRLB & 0b11111000) | 0b00000111)
4. A named constant. OK if I name one I have to name them all, that is 2^8 permutations........ why does it need naming and further obfuscating? at some point register bits need setting to 0 and 1. Do you make up constants for this stuff when you put such code inline in your main program? making it a constant technically requires an additional .c file.
5. "CLK_PER is THE name of the periphery clock in the datasheet, I can't think of a better name myself.
That's not how I'd do it.   
Code: [Select]
// Assign bits in x defined by mask to reg, LSB at bit pozn. Other bits of reg left unchanged.
#define WRITEBITS(reg, pozn, mask, x) (reg^=(reg^((x)<<(pozn)))&((mask)<<(pozn)))
//...

// CNTMODE[2:0] selects Timer Mode
#define TCB0_MODE_POZN 0
#define TCB0_MODE_MASK 0b111
// Timer modes in consecutive ascending order
enum {  TCB0_MODE_PERIODIC_INTERRUPT=0,
        TCB0_MODE_TIME_OUT_CHECK,
        TCB0_MODE_EVENT,
        TCB0_MODE_FREQ_MEASUREMENT,
        TCB0_MODE_PW_MEASUREMENT,
        TCB0_MODE_FREQ_PW_MEASUREMENT,
        TCB0_MODE_SINGLE_SHOT,
        TCB0_MODE_8BIT_PWM };

#define SET_TCB0_MODE(mode) WRITEBITS(TCB0.CTRLB, TCB0_MODE_POZN, TCB0_MODE_MASK, (mode))
then invoke with a function-like macro call. e.g:
Code: [Select]
SET_TCB0_MODE(TCB0_MODE_FREQ_MEASUREMENT);
Note that both the bit constants to be assigned and the mask for them are shifted 'up' the register by pozn so that enum can be used to declare them even for groups of bits that don't include the LSB of the register.  If you need to skip a bit value in the enum, e.g. 0b101, declare it as ..._RESERVED101
« Last Edit: August 21, 2018, 08:00:57 am by Ian.M »
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21658
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #13 on: August 21, 2018, 08:11:20 am »
I still don't get why you're going and inventing your own thing that's not adding functionality to the built in libraries, and is different from industry standards so will therefore bite some poor programmer who has to maintain it in some years.  Or some weeks, since IIRC you said this is supposed to be very portable right out the door or something?

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #14 on: August 21, 2018, 08:48:13 am »
Code: [Select]
SET_TCB0_MODE(TCB0_MODE_FREQ_MEASUREMENT);
i dont like this "still the machine/register code" naming. in the end, few months from now we have to reopen datasheet to see what its all about. i prefer something like human friendly meaning such as...
Code: [Select]
TIMER_MODE(TCB0_MODE_FREQ_MEASUREMENT);or
Code: [Select]
SET_PWM_TIMER_MODE(TCB0_MODE_FREQ_MEASUREMENT);whatever... so our code can become self documenting re explaining what the datasheet tries to do. but as i said, i dont know what the register actually do i may be mistaken in the naming and you can do whatever you think most readable to you. we are here just to advice and sharing thoughts ;) but ymmv.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #15 on: August 21, 2018, 09:08:54 am »
In general, I'm mostly with you on the naming thing, but for this usage case, I was only going on what Simon provided without reference to the datasheet. 

Unless you want to write yet another thin hardware abstraction layer for supposed portability, with constants for all possible modes of all possible timers that will be translated on a per timer basis to the correct mode bits for that timer,  (which IMHO is *NOT* a good idea:
as the hardware abstraction layer documentation is almost invariably significantly poorer than the datasheet), the psuedofunction macro name cannot sensibly be detached from the register name, as that provides the vital visual check that you are using the right group of constants with it.   

I suppose you could name the constants TIMER0_MODE_.... and the function TIMER0_MODE(), but as you will definitely need the datasheet open anyway, there's little to be gained.
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21658
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #16 on: August 21, 2018, 09:14:06 am »
That's not how I'd do it.

...

then invoke with a function-like macro call. e.g:
Code: [Select]
SET_TCB0_MODE(TCB0_MODE_FREQ_MEASUREMENT);
Note that both the bit constants to be assigned and the mask for them are shifted 'up' the register by pozn so that enum can be used to declare them even for groups of bits that don't include the LSB of the register.  If you need to skip a bit value in the enum, e.g. 0b101, declare it as ..._RESERVED101

This is good, and only a modest variation on the way Atmel did it (at least for the MEGA family) already.  A random example from an xmega header:

Code: [Select]
/* Quadrature Decoder Index Recognition Mode */
typedef enum EVSYS_QDIRM_enum
{
    EVSYS_QDIRM_00_gc = (0x00<<5),  /* QDPH0 = 0, QDPH90 = 0 */
    EVSYS_QDIRM_01_gc = (0x01<<5),  /* QDPH0 = 0, QDPH90 = 1 */
    EVSYS_QDIRM_10_gc = (0x02<<5),  /* QDPH0 = 1, QDPH90 = 0 */
    EVSYS_QDIRM_11_gc = (0x03<<5),  /* QDPH0 = 1, QDPH90 = 1 */
} EVSYS_QDIRM_t;

"_gc" stands for "group configuration", so it is the pattern of bits to set for the desired configuration.  The register is masked with the "_gm" (group mask), and the individual bits with "_bm" (bit mask).

Therefore, a basic modify statement has the form:
Code: [Select]
port.register = (port.register & ~port_bitgroup_gm) | port_bitgroup_state_gc;
The "& ~" reads the existing register value and zeroes the desired bits; the | puts back in the desired bits.  (The bitmasking can be omitted in the initialization routine, where you don't need to worry about the initial state of other bits in the register.)

The only reason you should need/want to get fancier, is to be able to change all "port.register" and bitgroup/state references, to a more general definition, in your own headers.

This is more or less what Ian is doing: putting the whole assignment into a macro function.

By encapsulating the assignment in a more general macro, you only have to change, say, a few dozens of register, bit and group names.

You definitely don't want to maintain exhaustive lists of bits, that will accumulate errors faster than you can say "refactor"!

At the very least, if you insist on building such lists, write a tool to generate them!  That's how the pros make their headers (well, at least I would hope so..).  That's also what their headers are for.  Use them!

With this additional level of naming indirection, you can -- if nothing else -- use them in the same way as the XMEGA style headers, even for platforms that don't use that format (e.g., original MEGA).  You can get consistent naming conventions across families, or sub-families anyway.  It's probably a fair method even to support completely different platforms, too (ARM?)!  Though, that's probably optimistic, and  you may need more (or fewer) statements, on platforms quite that different (i.e., wider-bit devices probably use fewer registers to hold all their control/status bits).

Generality is the key here.  You don't want to go more specific, less general.  You must only go more general.  To go more specific, means more code refactoring.  More work, more frustration!

It also means this: if you don't know, in what directions you should generalize -- if you aren't very familiar with the ecosystems of microcontrollers in general -- you probably shouldn't do it at all, and just leave it at the family level.

Make it obvious to the reader, which functions/defines need to be checked/changed, to migrate to a different device/family, and leave it at that.

Better still, if it's an open project: let other, more experienced programmers fork and improve it.  If you don't have that kind of breadth of knowledge, don't make it up as you go -- take advantage of those more experienced!

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8168
  • Country: fi
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #17 on: August 21, 2018, 09:56:56 am »
Didn't see anyone mention this yet, but as a general note, when you want to create a function-like macro in C preprocessor, you need to do it like this:

#define do_something() do{ your_actual_code } while(0)

This way, the macro is actually usable like any function would be. do { } while(0); always runs once (and doesn't generate any extra instructions). It's syntactical boilerplate.

This looks absolutely stupid and totally illogical (google for it to find reasons and explanation why you need this), but C preprocessor just is this way, and you need to live with this. C is far from perfect and many details are slightly broken, but many alternatives proposed over the years have had more fundamental problems.

Edit: removed excess semicolon.
« Last Edit: August 22, 2018, 08:26:35 am by Siwastaja »
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #18 on: August 21, 2018, 10:25:54 am »
Didn't see anyone mention this yet, but as a general note, when you want to create a function-like macro in C preprocessor, you need to do it like this:

#define do_something() do{ your_actual_code } while(0);
You want to drop the final semicolon though.
 
The following users thanked this post: Siwastaja

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #19 on: August 21, 2018, 11:31:54 am »
Yes.  However *some* compilers are borked and don't optimise away the traditional do{ .... }while(0) wrapper.  Finger of shame pointed at older versions of Microchip XC8 in FREE mode!  |O

That's why I wrapped it in () and made sure its contents are a valid expression.  It serves the same purpose of making the macro act as if it was a single native C statement to surrounding blocks and flow control, returning the register value, which is discarded when its invoked.   

I suppose one could try a ((void)( ... )) wrapper to discard the return value.

Another trap is parameters that have side effects when evaluated.   A C function evaluates them once when its called, but the macro evaluates them each time they are used, so if it use any of them more than once, it wont behave like a function.
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #20 on: August 21, 2018, 11:42:16 am »
If I had a dollar for every time I've fixed someones code simply by moving the // comment in a #define to the line before.

One of my rules for writing portable code is never put a comment on the same line as a #define. True, it won't bite you 99.9% of the time, but finding those 0.1% problems makes up for it!


Oh so I am allowed a comment in the header file. yes if not all preprocessors ignore // and everything after it sure.
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #21 on: August 21, 2018, 11:49:42 am »
I'm sorry but for years people have put in their code some register anded and ored to set certain bits with a numerical value. I put it behind a macro and now that number has to be a constant??? what the fuck are you all on about???? jesus christ! you want me to either create a constant whoes name if generic will be erm... let me think.... the number it represents and if i do them specific I'll just be making multiple constants that have the same values....

Indeed, coding is a sodding religion!!!!!!!!!!!!!!!!!!
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #22 on: August 21, 2018, 02:22:36 pm »
Indeed, coding is a sodding religion!!!!!!!!!!!!!!!!!!
Isn't it amazing how much discussion just a single line of code can generate? We are Artists. (*cough*) And coding styles are like snowflakes...  :palm:

If Kernighan and/or Ritchie posted code on the internet, it would probably be ripped to shreds. So don't feel too bad about the volume of discussion.

There have been lots of good suggestions in this thread. Now it's up to you to soak that all in and decide whether to go back and refactor1 working code to make it cleaner, safer, or whatever. None of this stuff will matter if you're at the, "I just want fscking thing to work!" stage. But if you're trying to convince other programmers to use your shiny new library of goodness, removing some of the objections listed here might be a good idea.

-----------

1. Real programmers don't change code, they "refactor" it, which sounds a lot more impressive.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3140
  • Country: ca
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #23 on: August 21, 2018, 02:36:01 pm »
If I had a dollar for every time I've fixed someones code simply by moving the // comment in a #define to the line before.

You wouldn't earn a single dollar.

One of my rules for writing portable code is never put a comment on the same line as a #define. True, it won't bite you 99.9% of the time, but finding those 0.1% problems makes up for it!

Could you show a single example of how this can cause a problem?

 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: gb
Re: [AVR GCC] Error called object is not a function or function pointer
« Reply #24 on: August 21, 2018, 03:08:44 pm »
I'm sorry but for years people have put in their code some register anded and ored to set certain bits with a numerical value. I put it behind a macro and now that number has to be a constant??? what the fuck are you all on about???? jesus christ! you want me to either create a constant whoes name if generic will be erm... let me think.... the number it represents and if i do them specific I'll just be making multiple constants that have the same values....

Indeed, coding is a sodding religion!!!!!!!!!!!!!!!!!!

You have demonstrated numerous times that you don't yet fully understand some pretty fundamental concepts in C (e.g. integer promotion, const values etc.), so why do you feel qualified to criticise both the language and peoples advice on how to use it?

ORing a value with zero is pointless.  Even though the optimiser should strip it out it adds nothing to the readability of your code and arguably detracts from it, so why do it?

You said you'd need to define 2^8 symbols for every register value but this isn't true for typical peripherals that use one or more bits per register to control specific functions.  You define symbols for each function in the register and then OR them together.  Usually these are already defined for you in a target specific header that comes with the compiler.  This way someone reading your code can see what it's doing without having to decode "magic" numbers.

Also using binary notation is not a good idea, this is a specific GCC extension and not supported by many/most compilers.  Use hex notation in these cases, it's very easy to mentally convert this to a binary sequence and is standard C.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf