Is it allowed to use varargs in an autosar C code? If not, why?
I'm not familiar with autosar. I found this document for c++14, which says:
Rule A8-4-1 (required, implementation, automated)
Functions shall not be defined using the ellipsis notation.
The reasoning is, that the ellipsis notation bypasses the type check. It is recommended to use variadic templates, function overloading or function call chain.
I haven't found any rule regarding varargs for autosar c. Is there any rule against varargs in c code? Is there any reason to avoid it? Is there any way to avoid it (I need to implement a logging function with string formatting)?
It is in Misra as well. Misra C is to C as AutoSAR C++ is to C++. It improves code quality, safety, and security. Lots of stdlib things in C is unsafe. But especially strings are a lot harder without things like variable arguments.
What I do (also for logging) is to create multiple functions that is appropriate to logging in specific situations. Some thing like log(text, int, int) and log(text, binary data block, size) etc. as required. Inside these functions there is calls to single variable argument function (usually snprintf) that prints everything to the log. You are not fully compliant but you are close and the use of variable arguments is contained to a specific area of code. If you need to be fully compliant the code is decoupled and easier to change.
Related
I have code that gives me an error. Implicit declaration of isNumericFloat.
I want to know if the function:
isNumericFloat()
a built it function in C?
NO, it's not a "built-in" c function.1
This function is used somewhere in your code and it's not part of the standard library. In fact, just because it uses camel case which is not very common in c code it seems like an odd function written by a not so c-ish programmer, of course that's a subjective reason, but commonly c programmers would choose is_numeric_float().
You need to search your code to see if you can find it's defintion, but in the mean time you can provide a prototype, like
int isNumericFloat(float value); // I don't really know what arguments it takes
// but you can surely infer them from the code
before it's ever called in the code, if you do so one of these two things will happen
If there is a definition for the function somewhere, it will compile fine.
If there is no definition, the linker will tell you that there is/are undefined reference/s to it in the code.
1Strictly speaking, there are no built-in functions in c, there is something called the standard library (headers starting with std , like stdlib.h), and I mean that it's not part of such library.
I know that C uses pass-by-value and we can emulate pass-by-reference with the help of pointers. But, for example, in order to calculate a simple mathematical expression, how do I implement pass-by-name (which is kind of lazy evaluation but not exactly) in C?
C is only pass-by-value. You can't pass by reference or name. With the pre-processor you can do various hacks but not in the C language.
Sometimes, people call passing a pointer "pass-by-reference" but this is not the case. The pointer is passed by value like anything else. C++ is a different story but you asked about C.
You might also be interested in this article discussion this at length
The parameter substitution used by function-like preprocessor macros is sometimes described as being "pass by name".
I always asked my self this question, Why printf() in C was designed to accept any number of parameters, isn't that Overloading? if yes how does a pure structured language contains an Object oriented language concept like Method overloading?
isn't that Overloading?
No, there is no overloading in C. It is called a "variadic function".
And no, despite its appearance in C++ and absence from C, method overloading is not an object-oriented concept. It is featured prominently in rather old programming languages, such as Prolog, that are not object-oriented.
It isn't overloading.. any method that takes a variable number of argument is called a variadic function.
Variadic methods on wiki
This is called varargs (variadic number of arguments) and existed since the early days of C.
This has no relation with overloading.
In a sense, it is just 'an open prototype', expressing the fact that prototypes weren't always as strictly used as nowadays. The flexibility of C in this department stems from the way in which parameters are passed: the cleanup of parameters is the responsibility of the caller, which can know how much room they occupied at the required times.
Similar techniques would not have been possible (easy) with competing calling conventions (e.g. Pascal calling convention)
I'm following a guide to learn curses, and all of the C code within prototypes functions before main(), then defines them afterward. In my C++ learnings, I had heard about function prototyping but never done it, and as far as I know it doesn't make too much of a difference on how the code is compiled. Is it a programmer's personal choice more than anything else? If so, why was it included in C at all?
Function prototyping originally wasn't included in C. When you called a function, the compiler just took your word for it that it would exist and took the type of arguments you provided. If you got the argument order, number, or type wrong, too bad – your code would fail, possibly in mysterious ways, at runtime.
Later versions of C added function prototyping in order to address these problems. Your arguments are implicitly converted to the declared types under some circumstances or flagged as incompatible with the prototype, and the compiler could flag as an error the wrong order and number of types. This had the side effect of enabling varargs functions and the special argument handling they require.
Note that, in C (and unlike in C++), a function declared foo_t func() is not the same as a function declared as foo_t func(void). The latter is prototyped to have no arguments. The former declares a function without a prototype.
In C prototyping is needed so that your program knows that you have a function called x() when you have not gotten to defining it, that way y() knows that there is and exists a x(). C does top down compilation, so it needs to be defined before hand is the short answer.
x();
y();
main(){
}
y(){
x();
}
x(){
...
more code ...
maybe even y();
}
I was under the impression that it was so customers could have access to the .h file for libraries and see what functions were available to them, without having to see the implementation (which would be in another file).
Useful to see what the function returns/what parameters.
Function prototyping is a remnant from the olden days of compiler writing. It used to be considered horribly inefficient for a compiler to have to make multiple passes over a source file to compile it.
In C, in certain contexts, referring to a function in one manner is syntactically equivalent to referring to a variable: consider taking a pointer to a function versus taking a pointer to a variable. In the compiler's intermediate representation, the two are semantically distinct, but syntactically, whether an identifier is a variable, a function name, or an invalid identifier cannot be determined from the context.
Since it's not determinable from the context, without function prototypes, the compiler would need to make an extra pass over each one of your source files each time one of them compiles. This would add an extra O(n) factor for any compilation (that is, if compilation were O(m), it would now be O(m*n)), where n is the number of files in your project. In large projects, where compilation is already on the order of hours, having a two-pass compiler is highly undesirable.
Forward declaring all your functions would allow the compiler to build a table of functions as it scanned the file, and be able to determine when it encountered an identifier whether it referred to a function or a variable.
As a result of this, C (and by extension, C++) compilers can be extremely efficient in compilation.
It allows you to have a situation in which say you can have an iterator class defined in a separate .h file which includes the parent container class. Since you've included the parent header in the iterator, you can't have a method like say "getIterator()" because the return type would have to be the iterator class and therefore it would require that you include the iterator header inside the parent header creating a cyclic loop of inclusions (one includes the other which includes itself which includes the other again, etc.).
If you put the iterator class prototype inside the parent container, you can have such a method without including the iterator header. It only works because you're simply saying that such an object exists and will be defined.
There are ways of getting around it like having a precompiled header, but in my opinion it's less elegant and comes with a slew of disadvantages. Of couurse this is C++, not C. However, in practice you might have a situation in which you'd like to arrange code in this fashion, classes aside.
I was reading some code written in C this evening, and at the top of
the file was the function-like macro HASH:
#define HASH(fp) (((unsigned long)fp)%NHASH)
This left me wondering, why would somebody choose to implement a
function this way using a function-like macro instead of implementing
it as a regular vanilla C function? What are the advantages and
disadvantages of each implementation?
Thanks a bunch!
Macros like that avoid the overhead of a function call.
It might not seem like much. But in your example, the macro turns into 1-2 machine language instructions, depending on your CPU:
Get the value of fp out of memory and put it in a register
Take the value in the register, do a modulus (%) calculation by a fixed value, and leave that in the same register
whereas the function equivalent would be a lot more machine language instructions, generally something like
Stick the value of fp on the stack
Call the function, which also puts the next (return) address on the stack
Maybe build a stack frame inside the function, depending on the CPU architecture and ABI convention
Get the value of fp off the stack and put it in a register
Take the value in the register, do a modulus (%) calculation by a fixed value, and leave that in the same register
Maybe take the value from the register and put it back on the stack, depending on CPU and ABI
If a stack frame was built, unwind it
Pop the return address off the stack and resume executing instructions there
A lot more code, eh? If you're doing something like rendering every one of the tens of thousands of pixels in a window in a GUI, things run an awful lot faster if you use the macro.
Personally, I prefer using C++ inline as being more readable and less error-prone, but inlines are also really more of a hint to the compiler which it doesn't have to take. Preprocessor macros are a sledge hammer the compiler can't argue with.
One important advantage of macro-based implementation is that it is not tied to any concrete parameter type. A function-like macro in C acts, in many respects, as a template function in C++ (templates in C++ were born as "more civilized" macros, BTW). In this particular case the argument of the macro has no concrete type. It might be absolutely anything that is convertible to type unsigned long. For example, if the user so pleases (and if they are willing to accept the implementation-defined consequences), they can pass pointer types to this macro.
Anyway, I have to admit that this macro is not the best example of type-independent flexibility of macros, but in general that flexibility comes handy quite often. Again, when certain functionality is implemented by a function, it is restricted to specific parameter types. In many cases in order to apply similar operation to different types it is necessary to provide several functions with different types of parameters (and different names, since this is C), while the same can be done by just one function-like macro. For example, macro
#define ABS(x) ((x) >= 0 ? (x) : -(x))
works with all arithmetic types, while function-based implementation has to provide quite a few of them (I'm implying the standard abs, labs, llabs and fabs). (And yes, I'm aware of the traditionally mentioned dangers of such macro.)
Macros are not perfect, but the popular maxim about "function-like macros being no longer necessary because of inline functions" is just plain nonsense. In order to fully replace function-like macros C is going to need function templates (as in C++) or at least function overloading (as in C++ again). Without that function-like macros are and will remain extremely useful mainstream tool in C.
On one hand, macros are bad because they're done by the preprocessor, which doesn't understand anything about the language and does text-replace. They usually have plenty of limitations. I can't see one above, but usually macros are ugly solutions.
On the other hand, they are at times even faster than a static inline method. I was heavily optimizing a short program and found that calling a static inline method takes about twice as much time (just overhead, not actual function body) as compared with a macro.
The most common (and most often wrong) reason people give for using macros (in "plain old C") is the efficiency argument. Using them for efficiency is fine if you have actually profiled your code and are optimizing a true bottleneck (or are writing a library function that might be a bottleneck for somebody someday). But most people who insist on using them have Not actually analyzed anything and are just creating confusion where it adds no benefit.
Macros can also be used for some handy search-and-replace type substitutions which the regular C language is not capable of.
Some problems I have had in maintaining code written by macro abusers is that the macros can look quite like functions but do not show up in the symbol table, so it can be very annoying trying to trace them back to their origins in sprawling codesets (where is this thing defined?!). Writing macros in ALL CAPS is obviously helpful to future readers.
If they are more than fairly simple substitutions, they can also create some confusion if you have to step-trace through them with a debugger.
Your example is not really a function at all,
#define HASH(fp) (((unsigned long)fp)%NHASH)
// this is a cast ^^^^^^^^^^^^^^^
// this is your value 'fp' ^^
// this is a MOD operation ^^^^^^
I'd think, this was just a way of writing more readable code with the casting and mod opration wrapped into a single macro 'HASH(fp)'
Now, if you decide to write a function for this, it would probably look like,
int hashThis(int fp)
{
return ((fp)%NHASH);
}
Quite an overkill for a function as it,
introduces a call point
introduces call-stack setup and restore
The C Preprocessor can be used to create inline functions. In your example, the code will appear to call the function HASH, but instead is just inline code.
The benefits of doing macro functions were eliminated when C++ introduced inline functions. Many older API like MFC and ATL still use macro functions to do preprocessor tricks, but it just leaves the code convoluted and harder to read.