wackazong Posted September 20, 2008 Report Share Posted September 20, 2008 Hi!Another thing that occured to me today: Is it possible/recommended to pass arrays as function parameters? I defined a struct like:typedef union { struct { unsigned char RED; unsigned char GREEN; unsigned char BLUE; }; struct { unsigned char COLOR[3]; }; } led_color_t; This way, if I pass this variable to a function, lets say void SetColor(led_color_t color); I can go through the three colors in a loop (color[0], color[1], color[2]), and do not have to adress them each on their own in the code. Is that a bright thing to do? If I try, I get a compiler warning: structure '_color' passed as function argument changed to pointerIt seems that a pointer is passed instead of the variable, and it seems that this could be inefficient code. But actually I have no idea. Does anybody know whether this is recommended? I till stick to passing three unsigned chars red, green, blue until I know whether passing the array is a good idea.Thanks, ALEXander. Quote Link to comment Share on other sites More sharing options...
Narwhal Posted September 21, 2008 Report Share Posted September 21, 2008 You might want to post more details showing your function and how you are calling it. It'll help people correct your specific error. But that said, I think I can provide some help here.I can think of very very few cases with structures where you would ever want to pass them by value. The main reason you'd want to pass a struct by value would be if you wanted to modify the values without modifying the original structure values, but there are better ways to accomplish this even when you'd passes a pointer to the struct. Whenever you make a function call, the compiler must create assembly code which pushes your function parameters on a stack, then the function being called must pop them off of a stack. The more parameters, the more data-pushing-and-popping code needs to be create, and the more stack is consumed. When taken to extremes, this can equal a slow and inefficient app.When you pass a pointer to a structure, it is often smaller than the structure, because structures often contain multiple items. I believe on the PIC's used here that pointers are 3 bytes? Anyway, it boils down that passing pointers to structure is most likely the best way to pass a struct and will result in more efficient code.So, your function should be defined like this: void SetColor(led_color_t * p_color);This is not a multiplication :-) The * is letting the compiler know that the variable is a pointer.then you can access the elements of the struct using: p_color->COLOR[x]or.. p_color->RED p_color->GREEN p_color->BLUE Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 21, 2008 Report Share Posted September 21, 2008 hi alexander,first you have to know that an array variable in C is nothing else than a pointer to thedata of the array. if you address an element in the array, the compiler just shifts thispointer according to the field size. It's just a smarter way of dereferencing a pointer.the compiler also knows the field type and can handle it accordingly then.compiler warning: structure '_color' passed as function argument changed to pointerI think this happens:because you have a union, there are two possibilities for the compiler to handlethe passing of your var to the function: as three-bytes-data or as an array variable, which is a pointer.the optimizer finds that you just use the array type in your function and decides to pass it as a pointer, which makes sense because less data will be put on thefunction stack. In my eyes this is just an optimazation hint, and nothing is wrongwith your code.as long as you just read the data, there is no problem with that.If you would write, you would just change the original data, because your array var is a pointer to the data. It's a bit weired in conjunctin with theunion thing, e.g. what would happen if you do both in the function, writingto the single fields and the array fields? maybe then the compiler would copythe data, and the array-dereference would point to the copied data then?there are other optimizations like this, which will cause the compiler to throwa warning: 8.1.5 Loop ReversingThis optimization is done to reduce the overhead of checking loop boundaries for every iteration. Some simpleloops can be reversed and implemented using a “decrement and jump if not zero†instruction. SDCC checks forthe following criterion to determine if a loop is reversible (note: more sophisticated compilers use data-dependencyanalysis to make this determination, SDCC uses a more simple minded analysis). • The ’for’ loop is of the form for(<symbol> = <expression>; <sym> [< | <=] <expression>; [<sym>++ | <sym> += 1]) <for body> • The <for body> does not contain “continue†or ’breakâ€. • All goto’s are contained within the loop. • No function calls within the loop. • The loop control variable <sym> is not assigned any value within the loop • The loop control variable does NOT participate in any arithmetic operation within the loop. • There are NO switch statements in the loop.this is from the sdcc manual (I attached it to the post).I also found this about passing arrays to functions in c++:http://www.itee.uq.edu.au/~comp2303/Leslie_C_ref/C/SYNTAX/functions.htmlI believe that passing arrays as data to functions is not part the concept of C, because functionparameters will be hold on the the stack, which is limited. so for bigger data amounts you wouldpass a pointer anyway.I think I should study this passing issue a bit deeper too.correction: by default sdcc does not push the params/vars in a function to the stack.therefore functions are by default non-reentrant. to write a function that you can call recursively, you need to declarethe function with the keyword __reentrant (sdcc manual 3.7 Parameters & local variables). also checkchapter 8.2 ANSI Compliance.sdccman.pdf Quote Link to comment Share on other sites More sharing options...
stryd_one Posted September 21, 2008 Report Share Posted September 21, 2008 It seems that a pointer is passed instead of the variable,You win!It's in sdcc's manual (attached to the above post, downloadable from the website), and yes, all aggregates are passed as pointers in SDCC. When you use them in the function, this works out OK because the pointer still goes to the same data. I fell asleep while typing this, and the guys already did all the C-specifics, enjoy :) Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 21, 2008 Report Share Posted September 21, 2008 It's in sdcc's manual (attached to the above post, downloadable from the website), and yes, all aggregates are passed as pointers in SDCC.I'dont know which part of the sdcc manual stryd_one is referencing, but I found some interesting stuff aboutfunctions / parameters / structures in the manual's chapter '8.2 ANSI-Compliance':• structures and unions cannot be assigned values directly, cannot be passed as function parameters or assigned to each other and cannot be a return value from a function...so if you want to pass a structure variable to a function, it's only correct to declare it as a pointer (as Narwhal said), and copy the struct manually field by field if you need to work with a local copy of the data (which I think will not be necessary in most cases).So, your function should be defined like this: void SetColor(led_color_t * p_color); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.