I defined
enum_<mytype>("mytype")
.value("one",1)
.value("two",2)
;
in my BOOST_PYTHON_MODULE.
when I expose a class with a function taking a parameter of type mytype (essentially, an int), like:
void myfunc(mytype m) {
...
}
I get the following compiler warning:
dereferencing pointer 'p.2311' (or whatever) does break strict-aliasing rules
now, it is just a warning, and the code works perfectly with optimization enabled..
may I safely ignore the warning? am I missing something?
Thank you
It's hard to say exactly without seeing the warning, but it's most likely caused by some macros from Python headers. To be safe, compile the code that uses Python (and Boost.Python) with -fno-strict-aliasing.
Related
Coverity has complained that various function calls in our codebase are not checking the return value.
Unchecked return value (CHECKED_RETURN)3. check_return: Calling Append
without checking return value (as is done elsewhere 73 out of 78
times).
In the past, we would have simply resolved this issue (after double-checking that the return value really was not important) by casting the return to void (as discussed here):
(void)Foo.Append(bar);
However, we are moving towards enabling all warnings, and treating warnings as errors, so I'm a little concerned that the above code will generate an old-style-cast diagnostic. If that's the case, I will need to modify our code to the considerably uglier format:
static_cast<void>( Foo.Append(bar) );
However, both gcc and clang seem to be able to compile this code (the first form) without complaining. So I suppose the final form of my question is this: Is casting a function return to void considered an exception to the rule as far as C-style casts are concerned? Or do I need to double check my code and see if the lines in question aren't actually being included in those builds?
It's fine.
(void) f(x);
is always equivalent to a static_cast as per [expr.static.cast]/6:
Any expression can be explicitly converted to type cv void, in which case it becomes a discarded-value expression.
Converting the result of a function to void is the way to make an expression a discard-value-expression. Now, the C++ way should be static_cast<void>(...)but (void) ... is an idiom (and is shorter).
Since the latter is well-defined and really common in codebases, gcc1 and clang2 made it not trigger Wold-style-cast.
It's well-defined, recognized by major compilers. It's fine.
1) g++ documentation --- 3.5 Options Controlling C++ Dialect
-Wold-style-cast (C++ and Objective-C++ only)
Warn if an old-style (C-style) cast to a non-void type is used within a C++ program. The new-style casts (dynamic_cast, static_cast, reinterpret_cast, and const_cast) are less vulnerable to unintended effects and much easier to search for.
2) not documented
I'm working on a school project that involves porting a large piece of C++ code on an experimental piece of hardware. Unfortunately, that hardware is 64-bit and the code contains many instances of pointer arithmetic that expects pointers to be 32-bit, i.e. it often does reinterpret_cast<uint32_t>(ptr).
Going through them one by one would be very tedious and since this is an experimental project anyway, I'm happy to settle for a "hackish" workaround. So instead I modified the implementation of malloc to ensure it never allocates memory above the 4GB limit. Technically, these casts should therefore be valid.
Question is, how do I explain this to Clang? The error I'm getting is: error: cast from pointer to smaller type 'uint32_t' (aka 'unsigned int') loses information. Is there a way to disable it?
Thanks,
David
I was able to disable this with -fms-extensions after getting this from someone on the Cpplang Slack:
Looking at "DiagnosticSemaKinds.td" it shows up as err_bad_reinterpret_cast_small_int, https://github.com/llvm-mirror/clang/blob/release_50/include/clang/Basic/DiagnosticSemaKinds.td#L6193
There are two occurences in "SemaCast.cpp" -- one of which suggests it's sensitive to MS extensions, https://github.com/llvm-mirror/clang/blob/release_50/lib/Sema/SemaCast.cpp#L2112
One could try -fms-extensions (hopefully not -fms-compatibility), but that would bring all the shebang with it.
I agree that you should bite the bullet and fix the code to use the correct integer type. But to answer your question: No, you can't disable it, though you can work around it.
Many errors come from warnings. A good thing in general, but if you want to disable the warning, just do it. Since the culprit is probably something like -Wall which enables many warnings you should keep on, you should selectively disable this single warning. The error message mentions the diagnostic responsible for error message, e.g. ... [-Wextra-tokens] (if it doesn't, remove the -fno-diagnostics-show-option flag). You can then disable this diagnostic completely by adding -Wno-extra-tokens (again, the "extra tokens" warning is an example), or turn it into a non-fatal warning by means of -Wno-error=extra-tokens.
However, this specific error is not due to a warning and I can't find any option to disable errors (makes sense, since most errors are fatal).
But to just truncate the integer value and not having to fix all the wrong uses of uint32_t just yet, you could use static_cast<uint32_t>(reinterpret_cast<uintptr_t>(ptr)). Needless to say, this will still be wrong.
how about using uintptr_t, most of your pointer arithmetic may still works.
Save this piece of code as mycast.hpp and add -include mycast.hpp to your Makefile.
#include <cstdint>
template<typename U, typename T>
U Reinterpret_cast(T *x) {
return (U)(uintptr_t)x;
}
template<typename U, typename T>
U Reinterpret_cast(T &x) {
return *(U*)&x;
}
#define reinterpret_cast Reinterpret_cast
They should do their job unless your code is too tricky.
Your strategy will not work for stack-allocated objects, be careful!! You can insert some debugging/logging logic to Reinterpret_cast if necessary.
I hit this same problem in a project without C++11, and worked around it like this:
inline int PtrToInt(void* ptr)
{
void* clang[1];
clang[0] = ptr;
return *(int*)clang;
}
I have the following bit of C code:
int main() {
myFunctionABC(2);
return 0;
}
void myFunctionABC(int n) {
printf("%d\n", n);
}
So... this code is working and I don't understand why. I always thought that a C compiler would always need every referred function to be already "known", otherwise would fail the compilation process.
Why is this working?
There has never been any requrement to define functions before calling them in C or in C++ (as the title of your question suggests). What is required in C++ and C99 (and in some cases in C89/90) is to declare functions before calling them.
As for your code... Your code is not "working". The best you can hope for is that your code will produce undefined behavior that will just happen to resemble "working".
Firstly, the code will not even compile as C++ or as C99 (and you tagged your question as both C and C++). C++ and C99 unconditionally require functions to be declared before they are called.
Secondly, with C89/90 compiler the code might compile, but will produce the aforementioned undefined behavior anyway. Even in C89/90 calling variadic functions (like printf) without declaring them first is illegal - it produces undefined behavior.
For non-variadic functions calling them without declaring them is OK - the implicit declaration rules of C89/90 will take care of that. But these rules will make the compiler to conclude that your undeclared myFunctionABC function returns an int, while in reality you defined it as returning void - this discrepancy leads to undefined behavior as well. Most self-respecting compilers will at least warn you about the problem.
gcc rightfully complains:
make 4356180
4356180.c:6: warning: conflicting types for ‘myFunctionABC’
4356180.c:2: note: previous implicit declaration of ‘myFunctionABC’ was here
If I add -Wall, I get these at well:
make CFLAGS=-Wall 4356180
4356180.c: In function ‘main’:
4356180.c:2: warning: implicit declaration of function ‘myFunctionABC’
It is not erroneous to declare a function prototype before actually calling it even if its definition is in a subsequent location, but it is a good practice to help the compiler out, check this similar post
Recently I tried to use /Wall Visual C++ option to enable all warnings and found that the following code:
typedef BOOL ( WINAPI * TIsWow64ProcessFunction )( HANDLE, BOOL* );
TIsWow64ProcessFunction isWow64ProcessFunction = reinterpret_cast<TIsWow64ProcessFunction> (
::GetProcAddress( kernel32DllHandle, "IsWow64Process" ) );
spawned C4191:
warning C4191: 'reinterpret_cast' : unsafe conversion from 'FARPROC' to 'TIsWow64ProcessFunction'
Calling this function through the result pointer may cause your program to fail
If I use a C-style cast the same warning appears but now it mentions "type cast" instead of "reinterpret_cast".
The same warning is repeated for just any case I call GetProcAddress() and convert its return value to some usable function pointer.
How do I address these warnings? Do I need to make alterations to my code?
You are casting a FARPROC (function pointer with no args) to a function pointer with args. Normally this is a hugely dumb thing to do that will probably result in stack corruption.
Now it turns out that GetProcAddress() doesn't really return a FARPROC and you do actually know what you're doing -- but the compiler doesn't know that and it feels obliged to warn you.
The only way you can silence it is using a #pragma or a compiler switch to turn off the warning. It is ugly and messy, but that is Windows programming for you. :-)
As other answers have already mentioned, this is a useful warning. Normally, this type of coercion would be a serious bug hiding in your application.
Therefore, you probably don't want to disable it globally with a compiler switch. Yet you still need to call GetProcAddress, and you like your builds to compile cleanly without warnings.
You have two good options:
Suppress each individual warning using an MSVC-specific pragma. In a new line just above the maligned cast, add the following code:
#pragma warning(suppress: 4191)
This suppresses the warning for the very next line of code only, ensuring that it is not globally suppressed and you'll still get a warning if you try to do something stupid elsewhere in the code base. Of course, you'll need to add this each time you use GetProcAddress, which is kind of a pain. Worse yet, it's a non-portable, MSVC-specific extension that uglifies your code.
So, alternatively…
You can silence the warning by explicitly casting the result of GetProcAddress (a FARPROC) to void*, and then casting that void* to the specific function-pointer type. For example:
typedef BOOL ( __stdcall *TIsWow64ProcessFunction )( HANDLE, BOOL* );
TIsWow64ProcessFunction isWow64ProcessFunction =
reinterpret_cast<TIsWow64ProcessFunction>(
reinterpret_cast<void*>(
::GetProcAddress(hInstance, "IsWow64Process")));
This approach will work with other compilers, is slightly less ugly, and is arguably more semantically meaningful.
Basically the compiler cannot guarantee that the function is of the appropriate type, so it's unsafe for you to call the resulting pointer. However, in a VS program you don't have to link or load against the Windows .dlls explicitly, they will be loaded for you and any function in the Windows header is always available to use.
I was bothered also by these warnings as I use this sort of thing quite often. I liked #Cody Gray's answer as it suppresses the warning only at the point of use but doesn't filter out other possibly valid warnings.
I made a simple function_cast helper to make it a bit more c++ like:
template<typename Result, typename Original>
Result function_cast(Original fptr)
{
return reinterpret_cast<Result>(reinterpret_cast<void *>(fptr));
}
The OP's code becomes:
auto isWow64ProcessFunction = function_cast<TIsWow64ProcessFunction>(::GetProcAddress( kernel32DllHandle, "IsWow64Process" ) );
I'm compiling some c++ code in MinGW GCC 4.4.0, and getting warnings with the following form...
warning: invalid access to non-static data member '<membername>' of NULL object
warning: (perhaps the 'offsetof' macro was used incorrectly)
This problem seems familiar - something I've tried to resolve before and failed, I think, but a while ago. The code builds fine in Visual C++, but I haven't built this particular code recently in any other compiler.
The problem code is the following template...
template<typename T>
class c_Align_Of
{
private:
struct c_Test
{
char m_Char;
T m_Test;
};
public:
enum { e_Align = offsetof (c_Test, m_Test) };
};
Obviously I can probably use some conditional compilation to use compiler-specific functions for this, and I believe C++0x will (at long last) make it redundant. But in any case, I cannot see anything wrong with this use of offsetof.
Very pedantically, it's possible that because the T parameter types are sometimes non-POD, so GCC classes c_Test as non-POD and complains (and complains and complains - I'm getting nearly 800 lines of these warnings).
This is naughty by the strict wording of the standard, since non-POD types can break offsetof. However, this kind of non-POD shouldn't be a problem in practice - c_Test will not have a virtual table, and no run-time trickery is needed to find the offset of m_Test.
Besides, even if c_Test had a virtual table, GCC implements the offsetof macro using an intrinsic that is always evaluated at compile-time based on the static layout of that particular type. Providing a tool then whining (sorry, warning) every time it's used just seems silly.
Also, I'm not the only person around here who does this kind of thing...
Answer to legit-uses-of-offsetof question
I do remember having an issue with offsetof for this kind of reason, but I don't think the problem was this template.
Any ideas?
Oops...
The issue is with the c_Test struct being non-POD due to the T type being non-POD. Here's a quote from the GCC manual...
-Wno-invalid-offsetof (C++ and Objective-C++ only)
Suppress warnings from applying the
‘offsetof’ macro to a non-POD type.
According to the 1998 ISO C++
standard, applying ‘offsetof’ to a
non-POD type is undefined. In existing
C++ implementations, however,
‘offsetof’ typically gives meaningful
results even when applied to certain
kinds of non-POD types. (Such as a
simple ‘struct’ that fails to be a POD
type only by virtue of having a
constructor.) This flag is for users
who are aware that they are writing
nonportable code and who have
deliberately chosen to ignore the
warning about it.
The restrictions on ‘offsetof’ may be
relaxed in a future version of the C++
standard.
My problem is that almost all my T types have constructors, and are therefore classed as non-POD. I ignored this point as irrelevant earlier - and of course it should be irrelevant for offsetof in principle. The trouble is that the C++ standard uses the one POD vs. non-POD classification even though there are a number of distinct ways to be non-POD, and the compiler is correct to warn about non-standards-compliant use by default.
My solution for the moment will be the option above to suppress the warning - now I just need to figure out how to tell cmake to use it.