Is it possible that I call a c program from a stateflow chart, then I copy this chart, still in this same model, and execute both with out any conflict?
For example a C program like this:
int var; // var is global
int myfunction(int n)
{
var = var + n;
return var;
}
i mean, treat them like two different entities and won't mess up with global variable.
btw, also without rename the function in source code, I've got a big program :)
This is more a C - related issue.
If you are using the same C function that operates on a global, then yes, all calls to this function will operate on the same variable.
What you can do instead is make this variable local to each of the calling Stateflow states and then pass it to the C function. This way you should not have conflicts and be able to reuse your code.
It's also a good design choice since you otherwise are potentially hiding a state variable in the function i.e. outside of your state machine.
Related
My understanding is that C functions only work with copies of variables unless passed by address. However, the following appears to work OK, and I am confused as to why. I am accessing a global struct in a function and it appears to change the global value even though I am not passing the address.
Global struct:
cal{
int a;
int b;
}cal;
Function:
AlterCalAandCalB()
{
cal.a = 1;
cal.b = 2;
}
This appears to change the global variable not just inside function.
I rewrote the code to this, and the performance is identical:
AlterCalAandCalB(struct cal *ptrCal)
{
ptrCal->a = 1;
ptrCal->b = 2;
}
I am interested in learning the best practice, not just what works. I realize that global variables are not recommended but in this particular case it works for me. But I want to learn the best practice for pointers.
My understanding is that C functions only work with copies of variables unless passed by address.
That's slightly confused. C functions receive their arguments by value -- roughly speaking, they receive copies, including if the argument is the address of an object or function. This is about argument passing, not about the behavior of the statements in function bodies.
Every executable statement is inside a function body. There would be no point to "global" variables if functions could not share access to them.
I am interested in learning the best practice, not just what works.
Best practice is a matter of opinion, so it is off topic here. But note that if you are going to pass the address of an object to all functions that you want to access it (excluding main(), I suppose), then there is no point to declaring that object at file scope in the first place.
I want to speed up the processing of a sequential C program using multi-threading. My problem is that my C program has a lot of global variables. They are read and written by the functions in my C program. Therefore, it is prevented to parallelize functions together by multithreading because it no longer holds the exact result compared to running sequence programs.
I using OpenMP to handle my C program. However, I wanna refactor my C program to react above purpose before use OpenMP
Here my example:
int a = 5 ; // global variable
funcA () {
int b;
b = a + 5; // read a
}
funcB () {
printf("%d\n", a);
}
I don't wanna find the way to parallel complete funcA and funcB but I want reduce the dependency caused global variable (like variable a in above example).
There is no simple way to do a complicated thing. It can seem difficult sometimes to design a code without global variables even when coding from zero. I your case, the problem is significantly more difficult.
There is not (and cannot be) a generic solution about how to minimize the number of global variables.
The only thing which can be done is:
analyze the code base;
understand the purpose of the global variables and how they are used;
find a way to achieve the same behavior without using global variables.
Of course, it might be easier for some global variables to be dealt with than others. You may want to start with the former. Seeing success coming your way will help your morale during the task.
It might help you if you read about how to make code:
tread safe;
re-entrant.
Google can help you greatly on this.
In general it is not an easy task to remove global variables.
You need to go on a case by case basis.
What you really need to do is to try to pass the variables required as function parameters rather than having them as globals.
In this example given, i cannot give any solution without looking at how the functions funcA and funcB are called. You should try to pass the variable a as a parameter to both the functions. You may need to go back up a few functions until you get to a common function which ultimately calls both functions.
I'm going round and round in circles trying to work out how to implement variables that need to be accessed by multiple functions within a [.c] file.
I have been ploughing through thread after thread on Stack Exchange and other Google searches where the general [but certainly not unanimous] consensus seems to be that file-wide static variables are fine, yet, you should pass variables (or at the very least pointers to variables) into functions and not just have any old function access the static file-wide variable (i.e. one that is declared outside of any function). Some people have said file-wide statics are essentially as bad as globals, but give no indication of how to avoid globals if not with file-wide statics!
However, at some point, even if you pass pointers to the file-wide static variable from function to function, some function has to originally access that file-wide static variable. Also, I cannot see a way where just one function within the .c file can be the sole function that accesses that static variable, because not all functions that will need the static variable would go through one single function.
It seems to me that you could have a function that does nothing but holds a static variable and returns a pointer to that static variable. Any function that needs to access that variable calls that function, gets the pointer to the variable and does what it needs to do with the variable. This kind of thing:
struct PacketStruct* GetPacketStructPtr(void)
{
static struct PacketStruct Packet;
return &Packet;
}
I've seen some people here say, yep, that's how a singleton factory is built (whatever that is) and it's completely valid, yet others say it's dangerous (but without really explaining why it's dangerous), others have said it's poor practice (I think they said it was inefficient, but I've read so much today I could be wrong).
So, what I am trying to ascertain is this:
Are file wide variables OK?
If so, given that it seems so wrong just to have all functions access that file-wide static variable and not pass pointers to it [the static file-wide variable] - as much as anything to make function re-use with different variables possible - can you just decide the first function that needs to access the file-wide static does so and then passes pointers all the way down to other functions? I really hate the look of code that just access the file-wide static variable, even though it also seems a little daft passing a pointer to something that the function can access anyway.
If file-wide static variables are not valid, given that this is not multi-threaded and just a run-to-complete program on an embedded micro, can/should I use that way of passing a pointer to the function-wide static variable to any other function that needs access to the variable?
If none of the above, how on earth do you avoid the dreaded global variables? This question of not using globals seems to have been tackled a zillion times here but without any concrete examples of how to do it. There is an awful lot of contradictory advice knocking about here, let alone on the rest of the web!
I stress this is single thread, not re-entrant and all relatively simple.
Hopefully, this gives some more idea about what I'm trying to do:
#include "work_order.h
// This is work_order.c
// Nothing outside of this file needs to access the WorkOrder struct
static struct WorkOrderStruct WorkOrder;
// Package up a work order - *data is a pointer to a complete serial package
int16_t CableConnectOrder(uint8_t *Data)
{
if (UnpackagePortInformation(&WorkOrder.PortA,&Data) == CARD_UID_NOT_FOUND)
return CARD_UID_NOT_FOUND;
if (UnpackagePortInformation(&WorkOrder.PortB,&Data) == CARD_UID_NOT_FOUND)
return CARD_UID_NOT_FOUND;
AddNewKeysToWorkOrder(&WorkOrder,Data);
WorkOrder.WorkOrderType = CONNECT_CABLE_REQUEST;
WorkOrder.Flags.SingleEndedConnection = FALSE_BIT;
WorkOrder.Flags.PortACableRemoveRequest = FALSE;
WorkOrder.Flags.PortBCableRemoveRequest = FALSE;
return ConstructCableOrderRequest(&WorkOrder);
}
int16_t ConstructCableOrderRequest(struct WorkOrderStruct *WorkOrder)
{
// This function is accessed by other Work Order requests and does the rest of the // packaging of the work order
// It can also pass the work order information further down
DoOtherStuff(WorkOrder); // Kind of further passing that might happen
}
int16_t CheckAdditionalInfoAgainstWorkOrder(struct WorkOrderPortUpdateStruct *Update)
{
// Compare connection information against the previously set-up work order
// Needs to access the static WorkOrder structure as well. Also, can call other
// functions that needs to access the static function
WorkOrder.Foo = Update->bar;
DoYetMoreOtherStuff(&WorkOrder); // This is not real code, but the general kind of idea
}
More information on what you're doing would be helpful. I often do embedded system programming where globals/file-wide statics are an absolute must due to interrupts. If that is what you're working on - go for it.
Re: A single function that creates the variable and passes a pointer to all other functions...
Your "single function" would be main. I'll often create code like so...
struct PacketStruct {
char name[128];
uint8_t age;
float bac;
}
void setup (PacketStruct *packetStruct, ...);
void foo (PacketStruct *parameter);
void bar (PacketStruct *parameter);
int main (void) {
PacketStruct ps;
// Initialize all variables"
setup(&ps);
// Run program
foo(&ps);
bar(&ps);
return 0;
}
void setup (PacketStruct *packetStruct, ...) {
strcpy(packetStruct->name, "Squidward");
packetStruct->age = 16;
packetStruct->bac = 0.11;
}
I like this because ps is not a global variable, you do not have to dynamically allocate memory (though you could just as easily do so), and it becomes accessible in all functions.
Again, if you post your full code (or a snippet showing how it's used) we might be able to give you some applications specific advice.
-Edit-
Since you're mentioning file-wide, I'm guessing that means you're not using this variable in the same file as main. In that case, my sub-files will have functions like filename_init(...)...
/* File: FooBar.c
*/
#include "FileWithPacketStructAndOtherCoolThings.h"
// "g_" sits in front of all global variables
// "FooBar_" sits in front of all file-wide statics
static PacketStruct g_FooBar_ps;
FooBar_init(void) {
strcpy(g_ps->name, "Squidward");
g_ps->age = 16;
g_ps->bac = 0.11;
}
I am trying to write a program where I have to call some functions through a (shared) library (its source is available). The C code for the library has several global variables, and many functions change the values of these global variables. What I have to do in my program requires that each function call that I make gets to work with a fresh set of variables.
For example, let this function be a part of the library:
int x = 1;
int foo()
{
int a = 0;
//do somethings to 'a'
//...
x++;
return a;
}
Now every time I invoke foo() from my program, the value of x gets update from 1 to 2 then 3 then 4 and so on... I am try to construct a program so that every time foo() is invoked, it sees x = 1.
I am sorry to say that my knowledge of how C/linux treat these variable spaces is insufficient, so this question may seem vague. The above is just a small example; in reality, there are so many variables that is practically impossible to reset their values manually.
What may be the best way to compile that library and/or use it my program so as to refresh the variables?
(On a side note, what I am also trying to do is to parallelize calls to foo(), but because of the shared variables, I cannot do that.)
EDIT:
When working on some web dev projects, I used to encapsulate some code in webservices and then invoke those services from the main program. Does a similar framework exist in C/Linux? Please note that functions are returning data.
You have discovered one of the main reasons that global variables (or global state in general) are a really bad idea.
Since you have access to the source, I would suggest investing some time to refactor the source code.
You can achieve the ability to parallelize calls to foo with the following strategy:
Gather up all of the global variables into a single struct. Call it something like Context.
Change each function that acts on a global variable to take a pointer to a Context, and change the function to update the variables in the Context instead of updating global variables.
Now each thread that wants to use the library can create a new Context and pass that into foo and related functions.
If it's not feasible to make such a change to the source code, you can use more than one CPU core by starting child processes. Each child process has it's own memory space. That option is not nearly as efficient as using multiple threads.
I have no answer in details. But you can try one of the following:
unload and load library
try to clear library's .bss and fill .data section with values from the library (ref dl_iterate_phdr() call).
I'm refactoring "spaghetti code" C module to work in multitasking (RTOS) environment.
Now, there are very long functions and many unnecessary global variables.
When I try to replace global variables that exists only in one function with locals, I get into dilemma. Every global variable is behave like local "static" - e.g. keep its value even you exit and re-enter to the function.
For multitasking "static" local vars are worst from global. They make the functions non reentered.
There are a way to examine if the function is relay on preserving variable value re-entrancing without tracing all the logical flow?
Short answer: no, there isn't any way to tell automatically whether the function will behave differently according to whether the declaration of a local variable is static or not. You just have to examine the logic of each function that uses globals in the original code.
However, if replacing a global variable with a static local-scope variable means the function is not re-entrant, then it wasn't re-entrant when it was a global, either. So I don't think that changing a global to a static local-scope variable will make your functions any less re-entrant than they were to start with.
Provided that the global really was used only in that scope (which the compiler/linker should confirm when you remove the global), the behaviour should be close to the same. There may or may not be issues over when things are initialized, I can't remember what the standard says: if static initialization occurs in C the same time it does in C++, when execution first reaches the declaration, then you might have changed a concurrency-safe function into a non-concurrency-safe one.
Working out whether a function is safe for re-entrancy also requires looking at the logic. Unless the standard says otherwise (I haven't checked), a function isn't automatically non-re-entrant just because it declares a static variable. But if it uses either a global or a static in any significant way, you can assume that it's non-re-entrant. If there isn't synchronization then assume it's also non-concurrency-safe.
Finally, good luck. Sounds like this code is a long way from where you want it to be...
If your compiler will warn you if a variable is used before initialized, make a suspected variable local without assigning it a value in its declaration.
Any variable that gives a warning cannot be made local without changing other code.
Changing global variables to static local variables will help a little, since the scope for modification has been reduced. However the concurrency issue still remains a problem and you have to work around it with locks around access to those static variables.
But what you want to be doing is pushing the definition of the variable into the highest scope it is used as a local, then pass it as an argument to anything that needs it. This obviously requires alot of work potentially (since it has a cascading effect). You can group similarly needed variables into "context" objects and then pass those around.
See the design pattern Encapsulate Context
If your global vars are truly used only in one function, you're losing nothing by making them into static locals since the fact that they were global anyway made the function that used them non-re-entrant. You gain a little by limiting the scope of the variable.
You should make that change to all globals that are used in only one function, then examine each static local variable to see if it can be made non-static (automatic).
The rule is: if the variable is used in the function before being set, then leave it static.
An example of a variable that can be made automatic local (you would put "int nplus4;" inside the function (you don't need to set it to zero since it's set before use and this should issue a warning if you actually use it before setting it, a useful check):
int nplus4 = 0; // used only in add5
int add5 (int n) {
nplus4 = n + 4; // set
return nplus4 + 1; // use
}
The nplus4 var is set before being used. The following is an example that should be left static by putting "static int nextn = 0;" inside the function:
int nextn = 0; // used only in getn
int getn (void) {
int n = nextn++; // use, then use, then set
return n;
}
Note that it can get tricky, "nextn++" is not setting, it's using and setting since it's equivalent to "nextn = nextn + 1".
One other thing to watch out for: in an RTOS environment, stack space may be more limited than global memory so be careful moving big globals such as "char buffer[10000]" into the functions.
Please give examples of what you call 'global' and 'local' variables
int global_c; // can be used by any other file with 'extern int global_c;'
static int static_c; // cannot be seen or used outside of this file.
int foo(...)
{
int local_c; // cannot be seen or used outside of this function.
}
If you provide some code samples of what you have and what you changed we could better answer the question.
If I understand your question correctly, your concern is that global variables retain their value from one function call to the next. Obviously when you move to using a normal local variable that won't be the case. If you want to know whether or not it is safe to change them I don't think you have any option other than reading and understanding the code. Simply doing a full text search for the the name of the variable in question might be instructive.
If you want a quick and dirty solution that isn't completely safe, you can just change it and see what breaks. I recommend making sure you have a version you can roll back to in source control and setting up some unit tests in advance.