I have a project which involves writing a C program for some software used by my company. I want it to be as efficient as possible, but the way the software references the signals I'm working with is a little wonky. I'm working with 4 sets of 96 signals; these signals are grouped into 32 groups with 3 members each. Rather than generic functions to work with these signals (the generic functions exist, but there's no documentation on how they work), the auto-generated header file has defined a group of macros (I think) for each of these groups.
Each of the groups are defined as follows...
typedef struct {
//struct members
} AB_A_Group_A_Network
Each of those structures have a group of macros(?) defined like this...
void AB_A_Group_ZF_Network_Init(AB_A_Group_A_Network *pAbc)
{
double values[6]
...
pAbc->Member_1 = values[3] //array positions vary
pAbc->Member_2 = values[4]
pAbc->Member_3 = values[5]
}
The software's tech support suggested I do the following, but I was hoping there'd be a better way to do it. Of course this is a long method, but I can write it with a python script no problem, if need be. These 250+ lines of code will run every second in my application for each data set.
AB_A_Group_A_Network GroupA;
AB_A_Group_B_Network GroupB;
//...and so on
AB_A_Group_ZF_Network GroupZF;
AB_A_Group_A_Network_Init(&GroupA);
AB_A_Group_B_Network_Init(&GroupB);
//...and so on
AB_A_Group_ZF_Network_Init(&GroupZF);
CD_Array_Set(0,GroupA.Member_1); //a custom array function meant to interface with the software
CD_Array_Set(1,GroupA.Member_2);
//...and so on
CD_Array_Set(95,GroupZF.Member_96);
//...Repeat 3 times for 4 sets of data (Data sets A-D), with checks to see if that data exists
I thought of doing something like this, but I'm not sure you can use char arrays in this way. I'll add the disclaimer don't have much experience with C, so this might look/sound really stupid. This isn't working code, just a stream of consciousness. I'm also not sure if doing it in this way, if possible, would just end up losing efficiency. I'm completely open to other methods.
char groupName[70] = "AB_*_Group_*_Network";
char dataset = 'A';
char group = 'A';
char member = '1';
char groupInit[70]
//write a loop to increment dataset alphabetically
//check if dataset exists
groupName[3] = dataset;
//write a sub-loop to increment group alphabetically (each set has 32 groups)
groupName[27] = group;
//use groupName in place of struct name (not sure how or if this is possible with my current methods)
groupInit = strncat(groupName, "_Init", 5);
//use groupInit in place of _init macro name
//write a sub-loop to increment member numerically (each group has 3 members)
char member[10] = "Member_*";
member[7] = member;
CD_Array_Set(i,groupName.member);
Is the long method really the best way of doing this? Any advice you can offer is appreciated!
There's no way to refer to variables and type names dynamically from strings at runtime. But you can use token pasting in a macro to avoid all the repeated code.
#define INIT_GROUP(dataset, group) \
AB_ ## dataset ## _Group_ ## group ## _Network Group ## group; \
AB_ ## dataset ## _Group_ ## group ## _Network_Init(&Group ## group); \
CD_Array_Set(0,Group ## group .Member_1); \
CD_Array_Set(1,Group ## group .Member_2); \
...
CD_Array_Set(95,Group ## group .Member_96);
Unfortunately, there are no loops in the preprocessor, so you have to write all 96 CD_Array_Set lines in the macro.
With this macro, you can then write:
INIT_GROUP(A, A)
INIT_GROUP(A, B)
...
INIT_GROUP(A, ZF)
Auto generated C code
It is possible to do such things in C but it requires ugly Macros.
First thing i would look at is
An old Stackoverflow question: https://stackoverflow.com/a/12591965/8964221
And the mentioned gist in it: https://gist.github.com/epatel/3786323
BUT!
I would think about the time it would consume to have it bug free and working.
It won`t be that easy to transform it to ur needs.
Related
I want to complete a parsing about varlist declaration,
like varlist:id comma varlist|id.
At this time, I need to set up a list about var.
So I write this code:
varlist: id comma varlist{ createtnode($1.idcontext);}
|id{createtnode($1.idcontext);};
But I find $1.idcontext is not that idcontext I want which should be this id token's idcontext.
Now, $1.idcontext is this sentence 'varlist'. Without the code action, this grammar works correctly.
typedef struct{
int* TC;
int* FC;
}boolcode;
typedef struct {
char* idcontext;
int constvalue;
int chain;
boolcode ftentry;
}includes;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef struct{
int classify;
includes unique;
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
VARList: IDENcode COMMA VARList{
if(YYDEBUG)
{printf("6\n");
printf("%s\n",$1.idcontext);
}
varlistnode* newvar=malloc(sizeof(varlistnode));
newvar->varname=$1.idcontext;
newvar->value=0;
newvar->next=NULL;
mynotes->next=newvar;
mynotes=mynotes->next;
}|IDENcode{
if(YYDEBUG)
{printf("7\n");printf("%s\n",$1.idcontext);}
varlistnode* newvar=malloc(sizeof(varlistnode));
newvar->varname=$1.idcontext;
newvar->value=0;
newvar->next=NULL;
mynotes->next=newvar;
mynotes=mynotes->next;
};
The words wait recognize:
a,b,c,d
The result of printf() function:
7
d:
6
c,d:
6
b,c,d:
6
a,b,c,d:enter code here
The real problem in this program is not visible in this question because the bug is in your lexical scanner.
You haven't included the flex file in the question, but it's reasonable to guess that it contains something like this:
[[:alpha:]_][[:alnum:]_]* { yylval.unique.idcontext = yytext; /* INCORRECT */
return IDENcode;
}
It should read
[[:alpha:]_][[:alnum:]_]* { yylval.unique.idcontext = strdup(yytext);
return IDENcode;
}
yytext points into the scanner's internal buffer, whose contents are modified every time the scanner is called. What you're seeing is a mild version of this problem, because your input is very short; if the input were long enough that yylex needed to refill the buffer from the input file, then you would see complete garbage in your idcontext fields. If you want to use the string later, you need to make a copy of it (and then you need to remember to free() the copy when you no longer need it, which can be a bit of a challenge.)
The other possible issue -- and honestly I don't know whether you consider it a problem or not, because you did not specify what output you expect from your debugging trace -- is that your right-recursive rule:
varlist: id comma varlist { createtnode($1.idcontext); }
| id { createtnode($1.idcontext); }
ends up calling createtnode on the ids in reverse order, because a bison reduction action is executed when the rule is matched. Using right-recursion like that means that the first varlist action to execute is actually the one corresponding to the last id.
If you want the actions to execute left to right, you need to use left-recursion:
varlist: varlist comma id { createtnode($3.idcontext); } /* See below */
| id { createtnode($1.idcontext); }
Left-recursion has other advantages. For example, it does not require all the ids (and commas) to pile up on the parser's internal stack waiting for the final reduction action.
Again, you don't show enough of your code to see how you use the result of these actions. It looks to me like you're trying to create a global linked list of variables, whose header you store in a global variable. (mynotes evidently points to the tail of the list, so it can't be used to recover the head.) If that's the case, then the change above should work fine. But it would be more normal to make the semantic value of varlist a list header, avoiding the use of global variables. That would result in code which looked more like this:
varlist: id comma varlist { $$ = append($1, createtnode($3.idcontext)); }
| id { $$ = append(newlist(), createtnode($1.idcontext); }
I need to code an automata, and I bumped into this old need of a computed goto (ala fortran4 :) )
I need to code this in a portable ansi-C.
I want to stay away from the "don't do that", away from longjmp/setjmp, away from embedded ASM(), away from non ansi-C extensions.
Does anyone know how to do this?
Like I said in a comment, despite your plea to not use anything other than goto, standard C has nothing to offer.
Design your state appropriately, and pass a pointer to it to the handler functions for them to modify. That way the handler can setup the next function to call. Something like this:
struct state;
typedef void state_func(struct state*);
#define NULL_ACTION_ADDRESS (state_func*)0
struct state {
state_func *action;
int value1;
int value2;
};
#define INIT_STATE { initial_action, -1, -1}
state_func initial_action;
state_func handle_a;
state_func handle_b;
int main(void) {
struct state s = INIT_STATE;
while(s.action != NULL_ACTION_ADDRESS) {
(*s.action)(&s);
}
return 0;
}
void initial_action(struct state* ps) {
ps->action = &handle_a;
}
void handle_a(struct state* ps) {
ps->action = &handle_b;
}
void handle_b(struct state* ps) {
ps->action = NULL_ACTION_ADDRESS;
}
I think I got it, I reviewed all the various threads on this topics and I started to agree that that there where no ansi C solutions, yet I found an way to do this that fit my needs. All solution I saw on stackoverflow where based on the idea to 'get' the addr of a label, then stuff it into a table, then index this table and goto, this is both with gcc/clang non ansi extension or the asm extension.
I gave it another try tonite and got this.
In an include file named cgoto.h I have this
#ifndef CGOTO_dcl
#define CGOTO_dcl(N) int CGOTO_##N
#define CGOTO_LE(l) l,
#define CGOTO_LG(l) case l:goto l;
#define CGOTO_def(N) \
if(0){typedef enum {N(CGOTO_LE)} N; CGOTO_##N: switch(CGOTO_##N)\
{N(CGOTO_LG) default:CGOTO_##N=0;goto CGOTO_##N;}}
#define CGOTO(N,i) CGOTO_##N=i; goto CGOTO_##N;
#endif
The usage is like this
#include <stdio.h>
#include "cgoto.h"
int f(int x)
{ //...
CGOTO_dcl(gtb);
//...
# define gtb(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb);
//...
CGOTO(gtb,x);
l0: printf("error\n");
return(0);
//...
l1:return(11);
l2:return(22);
l3:return(33);
}
int main()
{ printf("f(0)=%d f(1)=%d f(2)=%d,f(3)=%d\n",f(0),f(1),f(2),f(3));
}
In this implementation, the cost of jumping is 2 jumps and a switch() that is sequential, then optimisable. So this is reasonably performing compared to function call, a little less performing than &&label solution at the cost of portability.
With this implementation, labels code (semantic actions) are not confined into a switch() so we can implement jump table with shared semantic actions.
The index is assigned to a local goto_table_index, making the function using this re-entrant (multi threadable), though the optimiser can remove altogether this temp assignment.
The 1st Label in a jump table is 'special' (on this implementation) in the sense that it catch index out of bound, the first label is the 'error' label. If your code is bullet proof, i.e there is no way you can get an out of bound index, then the 1st label has not particular semantic.
CGOTO_dcl(gtb);
Declare the jump table 'gtb' own index as an auto integer so reentrant.
# define gtb(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb);
Define a jump table named gtb, labels can be entered/removed with L(label) so it is pretty convenient, and this is symbolic by nature, i.e the labels are name with a meaning. With #define as a switch() case, labels addition/suppression often mean #define renumbering that is a problem.
The #define can be separated from the CGOTO_def() but it make more sense to keep them together. The CGOTO_def() though got to be placed after the function local declaration as it contain a switch() that is code.
A uniq jump table can be used in multiple place in the function.
CGOTO(gtb,x);
...
CGOTO(gtb,y);
A label may be entered in multiple jump table
# define gtb1(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb1);
# define gtb2(L) L(l0) L(l4) L(l5)
CGOTO_def(gtb2);
So all in all, this may looks ugly, yet, the jump table definition though 2 line the #define and the CGOTO_def() is manageable and practical, semi performant, and portable.
We are back to FTN4 :)
Cheers,
Phi
I have a daemon for a scientific instrument that needs to persist about 100 unique variables. Currently, these settings are stored in binary form at explicit addresses, and each is accessed with a unique getter and setter. This is completely unmaintainable. I'd like to group settings together in sensible structures and persist those structures into files. I'll also have default values in case of incomplete files. What library or technique will allow me to save and restore these structures with as few lines of code as possible?
The fastest/easiest way to serialize a C struct is to use X-macros. This lets you define related properties together and re-use elements. This example does not do any of the error checking that should be done but with an implementation less than 30 lines it will be hard to find a shorter one. More elaborate uses are possible like automatically creating getters and setters.
#include <stdio.h>
#define SETTINGS_TABLE \
X(float, "%f", foo, 2.71818) \
X(float, "%f", bar, 0.70711) \
X(int, "%i", baz, 42)
#define X(type, fmt, name, default) type name ;
struct Settings { SETTINGS_TABLE };
#undef X
#define X(type, fmt, name, default) default ,
struct Settings settings = { SETTINGS_TABLE };
#undef X
void dump(FILE *f)
{
#define X(type, fmt, name, default) fprintf(f, "%s=" fmt "\n", #name, settings.name);
SETTINGS_TABLE
#undef X
}
void load(FILE *f)
{
#define X(type, fmt, name, default) fscanf(f, #name "=" fmt, &settings.name);
SETTINGS_TABLE
#undef X
}
int main(int argc, char *argv[])
{
FILE *cfg;
cfg = fopen(argv[1], "r");
load(cfg);
fclose(cfg);
dump(stdout);
return 0;
}
You can't simply serialize them using a library if you want human-readable files. You need to write a function which, given a filename and the structures, will write the contents of the structures in the file.I'd suggest you use a one line = one member basis, but write the name of the member too, so that you'll find which members are missing, this way: name:value.
Then, another function will need to retrieve a structure from the file. Instead of writing your own format, you could use JSON with the jansson library. **EDIT: As the comments said, libjson is another alternative, usable both in C and C++.
"Shortest" have several meanings
fast to process
eating as little as memory as possible
easy and quick to code
I would suggest to use a simple textual format to serialize them, probably JSON (or maybe YAML or XML). The advantage of such formats is that they remain somehow human "readable" (at last for a programmer).
There exist a lot of JSON libraries (notably in C and C++): jansson in C, jsoncpp for C++, etc etc...
Does your scientific instrument runs only a tiny 8 bit controller? If yes, you might be constrained by code size...
And I suggest also to document the serialized format.
Some time ago we took over the responsibility of a legacy code base.
One of the quirks of this very badly structured/written code was that
it contained a number of really huge structs, each containing
hundreds of members. One of the many steps that we did was to clean
out as much of the code as possible that wasn't used, hence the need
to find unused structs/struct members.
Regarding the structs, I conjured up a combination of python, GNU
Global and ctags to list the struct members that are unused.
Basically, what I'm doing is to use ctags to generate a tags file,
the python-script below parses that file to locate all struct
members and then using GNU Global to do a lookup in the previously
generated global-database to see if that member is used in the code.
This approach have a number of quite serious flaws, but it sort of
solved the issue we faced and gave us a good start for further
cleanup.
There must be a better way to do this!
The question is: How to find unused structures and structure members
in a code base?
#!/usr/bin/env python
import os
import string
import sys
import operator
def printheader(word):
"""generate a nice header string"""
print "\n%s\n%s" % (word, "-" * len(word))
class StructFreqAnalysis:
""" add description"""
def __init__(self):
self.path2hfile=''
self.name=''
self.id=''
self.members=[]
def show(self):
print 'path2hfile:',self.path2hfile
print 'name:',self.name
print 'members:',self.members
print
def sort(self):
return sorted(self.members, key=operator.itemgetter(1))
def prettyprint(self):
'''display a sorted list'''
print 'struct:',self.name
print 'path:',self.path2hfile
for i in self.sort():
print ' ',i[0],':',i[1]
print
f=open('tags','r')
x={} # struct_name -> class
y={} # internal tags id -> class
for i in f:
i=i.strip()
if 'typeref:struct:' in i:
line=i.split()
x[line[0]]=StructFreqAnalysis()
x[line[0]].name=line[0]
x[line[0]].path2hfile=line[1]
for j in line:
if 'typeref' in j:
s=j.split(':')
x[line[0]].id=s[-1]
y[s[-1]]=x[line[0]]
f.seek(0)
for i in f:
i=i.strip()
if 'struct:' in i:
items=i.split()
name=items[0]
id=items[-1].split(':')[-1]
if id:
if id in y:
key=y[id]
key.members.append([name,0])
f.close()
# do frequency count
for k,v in x.iteritems():
for i in v.members:
cmd='global -a -s %s'%i[0] # -a absolute path. use global to give src-file for member
g=os.popen(cmd)
for gout in g:
if '.c' in gout:
gout=gout.strip()
f=open(gout,'r')
for line in f:
if '->'+i[0] in line or '.'+i[0] in line:
i[1]=i[1]+1
f.close()
printheader('All structures')
for k,v in x.iteritems():
v.prettyprint()
#show which structs that can be removed
printheader('These structs could perhaps be removed')
for k,v in x.iteritems():
if len(v.members)==0:
v.show()
printheader('Total number of probably unused members')
cnt=0
for k,v in x.iteritems():
for i in v.members:
if i[1]==0:
cnt=cnt+1
print cnt
Edit
As proposed by #Jens-Gustedt using the compiler is a good way to do it. I'm after a approach that can do a sort of "High Level" filtering before using the compiler-approach.
If these are only a few struct and if the code does no bad hacks of accessing a struct through another type... then you could just comment out all the fields of your first struct and let the compiler tell you.
Uncomment one used field after the other until the compiler is satisfied. Then once that compiles, to a good testing to ensure the precondition that there were no hacks.
Iterate over all struct.
Definitively not pretty, but at the end you'd have at least one person who knows the code a bit.
Use coverity. This is a wonderful tool to detect code flaws, but is a bit costly.
Although it is a very old post. But recently I did the same using python and gdb. I compiled following snippet of code with structure at the top of hierarchy and then using gdb did print type on the structure and re-cursed into its members.
#include <usedheader.h>
UsedStructureInTop *to_print = 0;
int main(){return 0;}
(gdb) p to_print
(gdb) $1 = (UsedStructureInTop *) 0x0
(gdb) pt UsedStructureInTop
type = struct StructureTag {
members displayed here line by line
}
(gdb)
Although my purpose is little different. It is to generate a header that contains only the structure UsedStructureInTop and its dependency types. There are compiler options to do this. But they do not remove unused/unlinked structures found in the included header files.
Under C rules, it's possible to access struct members via another structure which has a similar layout. That means that you can access struct Foo {int a; float b; char c; }; via struct Bar { int x; float y; }; (except of course for Foo::c).
Hence, your algorithm is potentially flawed. It's bloody hard to find what you want, which BTW is why C is hard to optimize.
Being a C novice I would like to hear what Macro "define"s developers are using. I've been thinking about putting these in a header to skip verbosity I've become used to:
#define TS_ typedef struct {
#define _TS(x) } x;
#define I(x)_ { int i; for ( i = 1; i <= x; i++ ) {
#define _I } }
Can I add \n \t etc within these macros? As I would like to pass on my sourcecode minus the extra include:
#define TS_ typedef struct {\n
#define _TS(x) } x;\n
#define I(x)_ { int i;\n\tfor ( i = 1; i <= x; i++ ) {\n
#define _I \t}\n}\n
Would these work?
ie: Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
Links to good preprocessor tips and tricks also appreciated.
Before you get started, do not use macro names that begin with an underscore - these are reserved for compiler and standard library writers, and must not be used in your own code.
Additionally, I would say that the macros you suggest are all very bad ideas, because they hide from the reader what is going on. The only justification for them seems to be to save you a very small amount of typing. Generally, you should only be using macros when there is no sensible alternative. In this case there is one - simply write the code.
You can put whitespace in by escaping the newline
#define SOMETHING whatever\
This is part of the macro
But as others have said it's not really a great way to to do this.
It would be much better to look into editor macros so you could type the shortcut and have the editor expand it.
You are headed into a wrong path. DO NOT make up your own cpp directives that are unfamiliar to others - this will make your code hard to understand, and at some point maintain.
Try to find some good C code to read - good C code does not use these things, for a good reason.
DON'T DO IT. Nobody else will be able to read your code.
As a cautionary example, check out Steve Bourne's original sources for the Bourne shell, where he used macros to write the code in a kind of pidgin Algol style.
You could do this, but this sort of "personal language" is not generally used in the C world, especially if you expect anybody else to read your code in the future.
If you're doing this just for yourself, then feel free to #define whatever you want, but expect that once you start working with (or for) anybody else, you won't be able to continue using this sort of thing.
Using C macros unnecessarily can lead you into a world of pain, especially if you attempt to use it to expand code. There are uses for C macros, but this is not it.
Edit: I realize that my answer is tangential to your question, but I thought I should mention this since you say you are a C novice. Search for "C macro pitfalls" to get a full list of reasons why not to use macros. It's been previously discussed here.
In general, I strongly agree with the other respondents who tell you not to define your own macros purely for the sake of saving typing. The obfuscation is not worth it. Also, the particular macros you suggest are heinous. However, in Stroustrup's 1st Ed, he does something I rather like (sometimes):
#define Kase break; case
I became accustomed to the Python elif construct, so I often define the following:
#define elif(test) else if(test)
My purpose in doing this isn't to reduce typing, it's to keep indentation logical while maintaining consistent code width (I don't let my code go wider than 80 characters). I say this because to me this...
if(...) ...
else if(...) ...
else ...
...should be...
if(...)
{
...
}
else
if(...)
{
...
}
else
{
...
}
With my macro this becomes:
if(...)
{
...
}
elif(...)
{
...
}
else
{
...
}
It is always better to pass the loop variable to the macro.
A block - a macro has certain optimization problems. All compilers do not guarantee an optimized obj code for the "block scope" variables.
for example, the following code, when compiled with out any optimization options to gcc, prints two separate addresses for &i. And the same code when compiled with -O2 option will print the same address in both the blocks.
{
int i;
printf("address of i in first block is %u\n", &i);
}
{
int i;
printf("address of i in sec block is %u\n", &i);
}
Naming the language constructs appropriately makes the code more readable.
I like your idea, if you put it in the following way.
#define GREEN 1
#define YELLOW 2
#define RED 3
# define NUM_COLORS 3
#define COLOR_ITER (color,i) \
for(i=GREEN, color = colors[i]; \
i < NUM_COLORS; \
color = colors[++i])
int colors[3] = {GREEN, YELLOW, RED};
int
fun () {
int j;
color_t clr;
COLOR_ITER(clr, j) {
paint(clr);
}
}
Here, regardless of how it is written, the macro, COLOR_ITER, by its name, implies that you are looping for all available colors and doing "something" for each color. And this is a very easy-to-use macro.
And your quesion
Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
As everybody explained preprocessor will not help you in this case.
You can use your editor commands to automatically format your code, as you type it.