This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
casting unused return values to void
C++ What is the purpose of casting to void?
After downloading and building the GDCM code using CMake, I stumbled upon this:
void error_callback(const char *msg, void *) {
(void)msg;
gdcmErrorMacro( "Error in gdcmopenjpeg" << msg );
}
What does the first line do? Never seen something like that. Keep in mind that I told CMake to build using Visual Studio 2010, if that matters.
It prevents unused variable warnings. Presumably the macro gdcmErrorMacro() can be #defined as an empty macro and msg would not be referenced in that case.
This prevents a compiler warning emitted when a function's formal parameters aren't used in the function.
It is a generally good idea to compile production code with warnings treated as errors, so this looks like an attempt to clear that up before msg was referred to in the macro use.
This could also have been taken care of by simply not naming a formal parameter in the first place -- in fact, that's what I'd do IRL if there is no mention of msg when using the macro:
void error_callback(const char *, void *) {
}
The parameter msg is not used by that function and the compiler will complain (warning) about unused parameters.
The (void)msg; line simply "uses" that parameter (with no effect). This way, the compiler does not generate the warning.
edit: actually, the function uses that parameter, but the macro gdcmErrorMacro could be set (through a compile-defined macro) to expand to... nothing (for example, to an empty do{}while(0); construction, as customary in the Linux kernel.
This way, the compiler will see nothing in the body of the function that makes use of the parameter msg (remember that the compiler sees the preprocessed source file, so the macros are already expanded).
In that case, after preprocessing, the compiler will see:
void error_callback(const char *msg, void *) {
(void)msg;
do{ }while(0);
}
and the sole "use" of the parameter msg would be that line (void)msg;.
Related
I am reading a C++ code and came across a function:
double Nm_poissons_ratio(double /*Temp*/)
{
double PR(0.0);
PR = 0.31;
return PR;
}
I don't understand what is the effect of /* */ characters which surround the Temp variable.
Thanks
If you write
double Nm_poissons_ratio(double Temp)
the compiler will warning. about an unused variable.
In this case, the coder wanted to retain the signature for some reason, but to avoid the warning. He/she therefore put a comment to show what it originally was.
Why is this the signature? It's hard to know.
Perhaps this is an intermediate version of the code, and he/she plans to use this parameter in the future (this is actually an excellent case to retain the warning).
Perhaps it's passed as a callback to some function that expects a specific signature.
It means that the function takes a double argument, but they are commenting out the name (hence the /* */) because the argument to be named.
Likely because the compiler will warn them about an unused formal argument, since they do not use Temp anywhere in the function.
All that is happening is the developer is commenting out a piece of code. Basically a comment tells the computer to ignore this piece of code. So, if you were developing a programming you would:
/* This is hidden to everyone BUT the programmer. */
I have an old C++ code that has this line of code:
int logprintf( const char* ptr, ... );
and I am not sure what does it do exactly? should I change the code in order to be able to compile the code with new versions of the compiler?! does anybody have an idea? any help would be appreciated.
That's just C code and any compiler made since the 1980s should be able to handle it. The definition is of a varidic function, or "varargs" in C parlance.
What that does is declare a method signature, nothing more. Presumably somewhere else, either in a library you link in or in a C or C++ file you compile there's a matching implementation.
Most printf-style functions do not have a fixed number of arguments. This is what the ellipsis ... represents, zero or more arbitrary arguments go there.
I am trying to convert a C code to C++. In my .c file I've definitions like this:
void services(void);
void transfers(void);
Further more, a thread will initialize the above two like this:
_beginthread((void*) services,0,NULL);
_beginthread((void*) transfers,0,NULL);
When I try to compile, I got the following error at both the places above like this:
Conversion from void* to pointer to non-void required an Explicit cast: Cannot convert parameter 1 from void* to void(_cdecl*)(void*)
I am confused about this, hope you guys make it clear for me :-)
The solution is to use functions of the correct type and not cast them. Ignore the parameter if it's not relevant to the code.
void services(void*);
void transfers(void*);
_beginthread(services, 0, NULL);
_beginthread(transfers, 0, NULL);
If you absolutely can't change the functions, e.g. if you don't have access to the sources, use wrappers:
void correct_services(void*) { services(); }
_beginthread(correct_services, 0, NULL);
The compiler is helping you here - don't try to work around it by lying to it.
It looks like you are trying to convert from C++ calling standard to C calling standard. cdecl stands for C declaration.
To manually define a function to be cdecl you can use void _cdecl funct();
Try:
_beginthread((void(_cdecl*)(void*)) services, 0, NULL);
What you were doing was explicitly casting the function pointer to a non-function pointer type (void *). This was OK. But the _beginthread function expects as its first parameter a function pointer of the correct type mentioned in the error message. So you need to fix your cast.
If you're about to downvote this answer, I'd appreciate to know the reason why. I know it would be much better if user2754070 wanted to change the prototype of services (see my comments below). However, what I'm suggesting works (the answer was accepted) and, as far as I know, it is safe and standard practice in C libraries spawning threads. If you think it's not, please explain why and I'll consider deleting the answer.
LLVM 2.1 has an option that enables warnings for "missing function prototypes." When enabled, the warning will complain about a file like this:
double square( double d )
{
return d*d;
}
void main()
{
// ...
}
The function "square" will trigger a warning because it is defined without having been declared (prototyped). You can eliminate the warning thus:
double square( double d );
double square( double d )
{
return d*d;
}
void main()
{
// ...
}
I've programmed in C++ for twenty years and I've never seen a warning like this. It does not seem useful to me.
By default, this warning is enabled in new Mac console projects (at least) in Xcode 4.1. Evidently someone found it useful enough to first implement it and then enable it by default.
Why is this a useful warning? Why does LLVM have it as an option? Why is the option enabled by default on Xcode?
The compiler uses the prototype declaration to match types for the function definition.
If you are writing the prototype in a header(interface) file and the implementation in the source file then this warning (by forcing you to provide a declaration, effectively) would prevent you from making a typo error where function definition is different than the one in declaration.
Though, without such an warning, you would get the errors while linking. One might end up wondering what the actual problem is(n number of reasons for linking errors).
The warning during compilation stage is much better indication of error than a linking error.
If could be useful to make sure every function is either visible from some header, or static.
I had cases where two files were linked together, even though none of them used the same header file.
Take this example:
int test()
{
return 0;
}
If there's no header, you can have a second file which does:
extern int test();
test();
If you are writing a library, this warning could tell you that someone could be using this function even if they were not supposed to, since this function is in no header. They should have been marked as static.
Prototype of "int test()" should be "int test(void)" then it's OK.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Weird MSC 8.0 error: “The value of ESP was not properly saved across a function call…”
I have an OBJ file for which I don't have any soure code. I have used it in another project without any problems. Now I am trying to use it in another project. Here is the way I declare it:
extern "C" bool FileCompare(char* file1, char* file2);
I use it in a function like this:
void myFunction() {
//some code
FileCompare(file1, file2); // file1 and 2 are char arrays
}
Then in my main code I call myFunction:
int main() {
... some code
myFunction()
}
When myFunction returns I get "The value of ESP was not properly saved across a function call." in Visual Studio 2010 debugger. However, I know for a fact that FileCompares (the function in the obj file) does its job. When I comment it out everything works fine. I have used this OBJ file in the past without any problems. Considering I don't have the source of the obj file, is there anything I can do to try to "patch" this problem?
Thank you very much
More details: I suspect that the code uses CALL without RET (its written in assembly).
EDIT: I don't know if what I say makes sense the way things work, but since the function corrupts the esp is there anyway to save it and restore it after the function returns?
This is either due to a bug in FileCompare() or mismatched calling conventions between the declaration and implementation of myFunction() and/or FileCompare().
You might be able to fix the problem with an appropriate specifier (like maybe __cdecl) on the prototype for FileCompare(). Or you might need to create an assembly language wrapper for the FileCompare() function that fixes things up (since you say that you no longer have the source for FileCompare()).
Figuring out exactly what's wrong without FileCompare() source might require stepping thorough the assembly in a debugger.
I run into a similar problem once when I was compiling one project against old header file that differed from the latest by one missing virtual function.