CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Condensing code problem.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rougie



Joined: 14 Jun 2006
Posts: 31

View user's profile Send private message

Condensing code problem.
PostPosted: Tue Sep 01, 2009 6:42 pm     Reply with quote

Hello,

I have been coding my project and seem to have created many functions which are exactly identical except for the pointer type that is passed in as the function parameter.

Now, as we all know, C is quite picky about types. But the problem is, that I would like to group all functions that have identical code in them and make just one function. So for example, lets take 2 functions that are identical in code contents, but the first one takes a pointer to a pc structure like this: *pc, and the second one takes a pointer to an lb structure like this: *lb. Since their code contents are identical, I would like to make one function that takes a void* and depending on the pointer type I pass when calling this function, we cast the pointer type to the current type and therefore, the function can continue using the code that works for both functions.

Here is an example which uses two functions (f1() and f2()) just because the pointer types we pass in are different. I find this very redundant when this scenario is omni present in our application. What do you guys do to compress functions with identical code into one while the types you pass in are different and must be casted appropriately.

The sample is a little tricky, please view it attentively to fully understand what I mean. Here's the code:

Device header file
Code:

#include <18f4685.h>
#device  *=16
#device  ICD=TRUE    // Original memory value: 49152
#case                        //TURNS ON CASE SENSITIVITY IN CODE
#fuses   HS,NOLVP,NOWDT,PUT
#use     delay(clock=40M, oscillator=10M)
#fuses   H4

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// TABLES
typedef struct tag_pc_table
{
long z;
long h;
}pc_table;

typedef struct tag_lb_table
{
long z;
long u;
}lb_table;

// OBJECTS
typedef struct tag_pc {
long w;
struct tag_pc_table *dc;    // Pointer to an array of tag_pc_table structs
} pc;

typedef struct tag_lb {
long w;
struct tag_lb_table *dc;    // Pointer to an array of tag_lb_table structs
} lb;

void f1(void *x)
{
pc *p = x;

p->w = 10;
p->dc[0].z = 20;
}

void f2(void *x)
{
lb *q = x;

q->w = 10;
q->dc[0].z = 40;
}

int main()
{
pc *a;
lb *b;

pc_table apc[] = {101, 201};  // Fill table
lb_table alb[] = {102, 202};  // Fill table

a = malloc(sizeof (struct tag_pc));
a->dc = apc;
f1(a);

b = malloc(sizeof (struct tag_lb));
b->dc = alb;
f2(b);

free(a);
free(b);
return 0;
}

It is important to note that the command lines in the functions:
Code:
p->dc[0].z = 20;
q->dc[0].z = 40;

change member data from different table structures!

What is important to note here, is that the above code is redundant and
f1() and f2() should be able to be reduced to just one function, something like this:
Code:

void fx(void *x)
{
x->w = 10;
x->dc[0].z = 20;
}

But this obviously doesn't work, we all know that a void* has to be casted to a type before we can use it. So what can we do to make fx() work no matter what type is passed into it?

I know we can use templates to get around this problem, but that's only in C++. But C doesn't offer templates. So now what?

All feedback appreciated.

Finest regards
Rob
andrewg



Joined: 17 Aug 2005
Posts: 316
Location: Perth, Western Australia

View user's profile Send private message Visit poster's website

PostPosted: Wed Sep 02, 2009 8:38 am     Reply with quote

If you have different structures (I'll note the example structures you gave may have different names, but they are otherwise identical), then the code required to access them will be different - you *must* have different functions.

You'll only be able to combine functions if you can combine the data structures.

Note that C++ template functions only give the appearance of one function. The compiler will actually generate as many internal copies of that function as needed.

FWIW, malloc and free make me very uneasy. I've never used them in any microcontroller project. They're really there just to help port existing code. If you're starting with new code, I would strongly recommend changing your approach so you don't use them.
_________________
Andrew
rougie



Joined: 14 Jun 2006
Posts: 31

View user's profile Send private message

PostPosted: Thu Sep 03, 2009 3:43 pm     Reply with quote

Hello andrewg,

Okay, well I did group my structures differently and found a work around.
Quote:

FWIW, malloc and free make me very uneasy. I've never used them in
any microcontroller project. They're really there just to help port existing
code. If you're starting with new code, I would strongly recommend
changing your approach so you don't use them.

No can do, I am already using them extensively. Anyways it isn't so bad,
malloc does what it has to do and everyones happy :-)

Thanks for your input!

Finest regards
Robert
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Sep 03, 2009 4:05 pm     Reply with quote

Quote:
No can do, I am already using them extensively. Anyways it isn't so bad,
malloc does what it has to do and everyones happy :-)
You do test the malloc to succeed, do you?
The test for a NULL returned is missing in the code shown...


FYI:
malloc is considered bad design in embedded applications because of the possible memory fragmentation it can cause. In a PC this isn't much of a problem because there is a huge harddisk for virtual memory and when things really get bad the user will just reset the PC. In an embedded processor like the PIC you have a tiny amount of RAM and in a device that should run for weeks unattended you want to avoid these errors.

I can imagine you don't want to change your program, but just as a test have it running for a few days. If it starts to show weird behaviour this might be your problem.
Guest








PostPosted: Fri Sep 04, 2009 3:51 pm     Reply with quote

Hello ckielstra,

Hmm! Several days, no, but it did run at a particular part of the program where no malloc are used for 12 to 20 hours at a time.

But I might just try to make it run one full week so it is executing different parts of the program with and without mallocs.

I will get back to you at this very post with the findings.

Thanks for your advice!

Regards
Rob
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group