Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I've recently learned that declare functions or/and variables as static can reduce footprints, but I can't figured out why. Most article online focus on the scope and readability but not mentioned any benefit about memory allocation. Does "static" really improve performance?
The static keyword is primarily about semantics, not about performance. If you want a variable that persists through multiple calls of the same function, declare it as static. If you don't want that, don't declare it as static. That said, static variables have a performance benefit, which is that they are only initialized once instead of every time the function is called. In other cases, static variables are slower as they are more likely to not be in the cache. Automatic variables are usually always cached as they are typically allocated on the stack, which is generally a hot area, caching-wise. For this reason, you should make lookup tables or constant variables static unless there is a special reason not to (e.g. some people use automatic constant variables as a token to pass to another function).
For functions, the same thing applies: Make a function static when you don't want to call it from other translation units. You should most definitely make all functions static for which this applies. On ABIs that need to preserve the ability for symbol interposition (i.e. the ability to exchange at load time the definition of a global symbol), compilers can only inline static functions. Also, the compiler can remove unused static functions from the binary. This is only possible if the entire translation unit is unused when the function is not static.
Whether using a static variable would improve efficiency depends on
many things, including the usage of the variable and the hardware
architecture of your processor. The C standard does not specify this.
If you need the variable to retain its value between one call of the
function and the next, it must have static storage duration.
Otherwise the only way to find out for sure is to code it both ways
and do timing tests.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I had some fun with imitating OOP in C, but I got somewhat discouraged when I understood that I'll have to call member methods like obj->method(obj, ...). Then I thought about cloning and modifying functions at runtime. Can I implement a function like strdup but for functions using a simple parser to identify the return opcode to stop copying and then modify a value in the function to point to the object the member method refers to so that I can use just obj->method(...)?
No, at least from what it sounds like you are asking, which is to modify functions at run-time. Modifying functions at run-time is possible but is difficult and requires considerable knowledge (and is system-specific). However, you seem to be asking to be able to execute a function and modify the function so that it does something with the object it is associated with. However, by the time the function is executing, there is generally no information about that object available: In a call like obj->method(…), there is generally no reference to obj included in the arguments. So even if you could modify the function at run-time, it does not have the information needed to do the job you want.
There are ways to do it at compile-time. That is how C++ developed. If that is a feature you want, the best approach is to use C++.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I was just watching this video on LinkedIn Learning that was talking about
Lookup tables and it mentioned that without the 'const' qualifier, the array will be allocated in RAM and initial assignment takes place during startup and the whole table would be stored twice - in RAM and ROM both.
Can someone explain this to me in a bit more detail? Why does it get stored twice? Does this mean that all variables/arrays without 'const' get stored twice? Would a switch case be better than lookup tables without const?
Thanks in advance.
Microcontrollers have usually (except the Flashless ones) much more FLASH than RAM. It would be a waste to place the constant data in the RAM.
When you use the const keyword most toolchains place the data in the .rodata section which is located in the read only memory - FLASH. Some uC types (AVRs for example) need to use special mechanisms to access this data, for most modern ones there is almost no difference (fast uC need to slow down read and write operations using wait states as FLASH is slower than SRAM)
you can also force the static const automatic variables to be placed in ROM by using attributes and pragmas
(gcc) static const char __attribute__((section(".rodata"))) x; (sections may may have different names - check your toolchain documentation)
But it works only with the global variables - most implementations place automatic const variables on the stack which is located in RAM
EDIT
The static const may be stored as well in the ROM only. But several years ago I had a bad experience with one of the uC gcc branches. To make sure - check what your toolchain is doing with this variables.
So the const is not necessary for lookup tables but it is logical to save the the (usually) very limited resource - the SRAM.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I had a couple thoughts on this. The first is that allocating global variables may be faster, since they are only allocated once, at the time the program is first spawned, whereas local variables must be allocated every time a function is called. My second thought is that since local variables are on the stack, they are accessed through the base pointer register, so the value stored in the base pointer must be decremented every time a local variable is accessed; global variables are accessed directly through their static addresses in the data segment. Is my thinking accurate?
It's rather inaccurate.
If you study computer architecture, you'll find out that the fastest storage are the registers, followed by the caches, followed by the RAM. The thing about local variables is that the compiler optimizes them to be allocated from the registers if possible, or from the cache if not. This is why local variables are faster.
For embedded systems, sure it might be possible to compile to a tiny memory model in which case your data segment may possibly fit into a modern controller's SRAM cache. But in such cases, your local variable usage would also be very tight such that they are probably operating entirely on registers.
Conclusion: In most cases, local variables will be faster than global variables.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
While going through a book on machine instructions and programs I came across a particular point which says that an assembler scans an entire source program twice. It builds a symbol table during the 1st pass/scan and associates the entire program with it during the second scan. The assembler needs to provide an address in a similar way for a function.
Now, since the assembler passes through the program twice, why is it necessary to declare a function before it can be used? Wouldn't the assembler provide an address for the function from the 1st pass and then correlate it to the program during the 2nd pass ?
I am considering C programming in this case.
The simple answer is that C programs require that functions be declared before it can be used because the C language was designed to be processed by a compiler in a single pass. It has nothing to with assemblers and addresses of functions. The compiler needs to know the type of a symbol, whether its a function, variable or something else, before it can use it.
Consider this simple example:
int foo() { return bar(); }
int (*bar)();
In order to generate the correct code the compiler needs to know that bar isn't a function, but a pointer to a function. The code only works if you put extern int (*bar)(); before the definition of foo so the compiler knows what type bar is.
While the language could have been in theory designed to require the compiler to use two passes, this would have required some significant changes in the design of the language. Requiring two passes would also increase the required complexity of the compiler, decreasing the number of platforms that could host a C compiler. This was very important consideration back in the day when C was first being developed, back when 64K (65,536) bytes of RAM was a lot of memory. Even today would have noticeable impact on the compile times of large programs.
Note that the C language does sort of allows what you want anyways, by supporting implicit function declarations. (In my example above this it what happens in foo when bar isn't declared previously.) However this feature is obsolete, limited, and considered dangerous.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have been told by more senior, experienced and better-educated programmers than myself that the use of function-pointers in c should be avoided. I have seen the fact that some code contains function pointers as a rationale not to re-use that code, even when the only alternative is complete re-implementation. Upon further discussion I haven't been able to determine why this would be. I am happy to use function pointers where appropriate, and like the interesting and powerful things they allow you to do, but am I throwing caution to the wind by using them?
I see the pros and cons of function pointers as follows:
Pros:
Great opportunity for code modularity
OO-like features in non-OO c (i.e. code and data in the same object)
How else could you reasonably implement a callback?
Cons:
Negative impact to code readability - not always obvious what function is actually called when a function pointer is invoked
Minor performance hit compared to a direct function call
I think Con # 1. can usually reasonably be mitigated by well chosen symbol names and good comments. And Con # 2. will in general not be a big deal. Am I missing something - are there other reasons to avoid function pointers like the plague?
This question looks a little discussion-ey, but I'm looking for good reasons why I shouldn't use function pointers, not opinions
Function pointers are not evil. The main times you "shouldn't" use them are when either:
The use is gratuitous, i.e. not actually needed for what you're doing, or
In situations where you're writing hardened code and the function pointer might be stored at a location you're concerned may be a likely candidate for buffer overflow attacks.
As for when function pointers are needed, Adam's answer provided some good examples. The common theme in all those examples is that the caller needs to be able to provide part of the code that runs from the called function. Without function pointers, the only way you could do this would be to copy-and-paste the implementation of the function and change part of it to call a different function, for every individual usage case. For qsort and bsearch, which can be implemented portably, this would just be a nuisance and hideously ugly. For thread creation, on the other hand, without function pointers you would have to copy and paste part of the system implementation for the particular OS you're running on, and adapt it to call the function you want called. This is obviously unacceptable; your program would then be completely non-portable.
As such, function pointers are absolutely necessary for some tasks, and for other tasks, they are a major convenience which allows general code to be reused. I see no reason why they should not be used in such cases.
No, they're not evil. They're absolute necessary in order to implement various features such as callback functions in C.
Without function pointers, you could not implement:
qsort(3)
bsearch(3)
Window procedures
Threads
Signal handlers
And many more.