i have this snippet of code that use an iterator on a list
for x:= range s.faces.Iter(){
x.Render()
}
as the compiler points, x is of type interface{} and there isn't a method (i interface)Render() defined in my code.
changing to
for x:= range s.faces.Iter(){
x.(faceTri).Render()
}
compile, because there is a method func (f faceTri) Render()
but upon execution this runtime error is raised:
panic: interface conversion: interface is *geometry.faceTri, not geometry.faceTri
(geometry is the package)
so, anybody can point me to a resource that explain the go way to use iterators + casting?
That's actually called a type assertion in go, not a cast (casts are compile time conversions between certain compatible type, i.e. int -> int32).
Based on the error you posted, you just have a tiny mistake in your code. The underlying type of x is *faceTri (a pointer to a faceTri structure), so the type assertion should be x.(*faceTri)
EDIT:
A few things to clarify and go beyond your question. A type assertion in go is not a cast, for example: interface_with_underlying_type_int.(int64) will panic, even though int can be cast to int64
Also, you can check a type assertion using the comma-ok idiom
not_interface, ok := some_interface.(some_type)
ok is a boolean indicating whether the conversion was successful, instead of causing a runtime panic.
Related
I don't understand this C26485 warning I receive.
My code is an exception handler:
catch (CDBException* e)
{
TCHAR szError[_MAX_PATH];
e->GetErrorMessage(szError, _MAX_PATH);
AfxMessageBox(szError);
}
It is saying:
Expression szError: No array to pointer decay (bounds.3).
Both GetErrorMessage and AfxMessageBox are flagging this.
It doesn't make sense to me. Thanks for your help.
This diagnostic is an unfortunate result of the code analysis taking too narrow a view, ignoring hints that are readily available. C26485 warns against array-to-pointer decay, one of C++' most dangerous features. When passing the name of an array to a function that expects a pointer, the compiler silently converts the array into a pointer to its first element, thereby dropping the size information that's part of the array type.
Clients that call into an interface that accepts individual arguments (pointer and size) to describe an array must make sure that the size actually matches that of the array. This has caused countless CVE's, and there's no reason to believe that the situation is getting any better. Array-to-pointer decay is dangerous and having tooling guard against it is great. In theory.
Here, however, things are different. The declaration (and definition) of GetErrorMessage have SAL Annotations that allow the compiler to verify, that pointer and size do match, at compile time. The signature is as follows:
virtual BOOL GetErrorMessage(_Out_writes_z_(nMaxError) LPTSTR lpszError,
_In_ UINT nMaxError,
_Out_opt_ PUINT pnHelpContext = NULL) const;
The _Out_writes_z_(s) annotation establishes a compile-time verifiable relationship between the pointer lpszError and its corresponding array's size nMaxError. This is helpful information that should be taken advantage of whenever possible.
First, though, let's try to address the immediate issue, following the recommendation from the documentation:
An explicit cast to the decayed pointer type prevents the warning, but it doesn't prevent buggy code.
The most compact way to turn an array into a pointer to its first element is to literally just do that:
catch (CDBException* e)
{
TCHAR szError[_MAX_PATH];
e->GetErrorMessage(&szError[0], _MAX_PATH);
AfxMessageBox(&szError[0]);
}
This fixes the immediate issue (on both function calls, incidentally, even if for different reasons). No more C26485's are issued, and—as an added bonus—passing an incorrect value as the second argument (e.g. _MAX_PATH + 1) does get the desired C6386 diagnostic ("buffer overrun").
This is crucially important, too, as a way of verifying correctness. If you were to use a more indirect way (say, by using a CString, as suggested here), you'd immediately give up on that compile-time verification. Using a CString is both computationally more expensive, and less secure.
As an alternative to the above, you could also temporarily suppress the C26485 diagnostic on both calls, e.g.
catch (CDBException* e)
{
TCHAR szError[_MAX_PATH];
// Decay is safe due to the _Out_writes_z_ annotation
#pragma warning(suppress : 26485)
e->GetErrorMessage(szError, _MAX_PATH);
// Decay is safe; the previous call guarantees zero-termination
#pragma warning(suppress : 26485)
AfxMessageBox(szError);
}
Which of those implementations you choose is ultimately a matter of personal preference. Either one addresses the issue, with the latter being maybe a bit more preserving as far as code analysis goes.
A word on why the final call to AfxMessageBox is safe: It expects a zero-terminated string, and thus doesn't need an explicit size argument. The _Out_writes_z_(s) annotation on the GetErrorMessage signature makes the promise to always zero-terminate the output string on return. This, too, is verified at compile time, on both sides of the contract: Callers can rely on receiving a zero-terminated string, and the compiler makes sure that the implementation has no return path that violates this post-condition.
As suggested by Andrew, I should post working code here.
Solution without using TCHAR
catch (CDBException* e)
{
e->ReportError();
e->Delete();
}
.
catch (CException* e)
{
CString strError;
e->GetErrorMessage(strError.GetBufferSetLength(_MAX_PATH), _MAX_PATH);
strError.ReleaseBuffer();
AfxMessageBox(strError);
e->Delete();
}
For the second example, selon IInsepctable this silences only the code analysis.
And to remember, usually you must delete the CException pointer, which you have forgotten here?
I have some psuedocode for a function to display a value and get a value
int getValue(){
int value;
// open file
// read line into "value"
if(error occurs){
// if file doesn't open or line was not an integer
/* Normally I would return something such as -1
but -1 in this case would be a valid value*/
value = ?
}
return value;
}
void displayValue(){
int value = getValue();
if(value is valid)
display(value);
}
As described in the code above, I would like to return that there was an error and let displayValue know that there was an error. But i want to accept negative,positive, and 0 from getValue.
Is there a better way to go about this? Does anyone have any advice?
Throw an exception. One of the advantages of C++ over C is that, when you have an error, you don't have to smuggle error codes out of the function, you can just throw an exception. If it's a truly exceptional case, most of the time the caller won't have anything useful to do with it anyway, so forcing them to check for it manually, then pass the error up the call chain is pointless. If they do know what to do with it, they can catch it.
This solution is also more composable. Imagine a scenario where A returns int, B calls A and returns a std::string based on it, and C calls B and returns class Foo based on that. If A has an exceptional condition that requires it to return an error, you can either:
Come up with some way to smuggle the error out of A as an int (or std::optional<int> or std::pair<bool, int> or whatever), then check for and convert that smuggled error to a different smuggled error for B, then check for and convert that to yet another smuggled error for C, then the caller of C still needs to check for that smuggled error and all three layers have to pay the price of the checks every time, even when all three layers succeeded, or...
You throw an exception in A, neither B nor C have anything useful to do with it (so they don't write any additional code at all), and the caller of C can choose to catch the exception and produce a friendlier error message if they so choose.
On modern architectures, the cost in the success case for #2 should be pretty negligible; the failure case might be more costly than the "check at every level case", but for something like "file doesn't exist" or "file contains corrupt data", it hardly matters if performance suffers, since you're probably about to exit the program (so speed doesn't count) or pop a dialog the user needs to respond to (the user is slower than the computer by many orders of magnitude).
There are several error handling approaches in C++:
The traditional way popular in C API's (also used by std::string algorithms) is to reserve at least one value as "invalid", which when returned would signal that there was an error, or that the value represents "no result". In case of error, the C API's would use the global errno to inform what error happened.
One of the features C++ introduced over the C language is exceptions. You can simply throw when error occurs. This is most appropriate for unexpected errors or pre/post-condition violations, rather than "no result exists" type situations.
Yet another way is to return both the value, and information about whether the result is valid. Old fashioned approach might be to return a pair of integer and boolean (or a named class that achieves the same). Alternatively, either value or error state can written into object passed through indirection. std::optional has been introduced into the standard library just for this kind of situation an is a great way of representing lack of result.
Latter approach can be further extended to not only return a boolean, but actual information about the error in similar way to the way exceptions do. The error information can also be wrapped with the value in a "variant" type so that they can share the space, as only one of them can exist at any time. This approach is similar to Maybe type in Haskell. There is a proposal to introduce a template for this purpose into the standard library.
Each of these approaches have their benefits and drawbacks. Choose one that is appropriate for your use case.
One option is to throw an exception when an error occurs. It's highly dependent on the rest of your project. Are Exceptions used all around ? Personally, I prefer more conventional old-school approaches. Mostly because people will start throwing exception everywhere, where it's not really exceptional and then it makes debugging much harder as the debugger keeps stopping for non-exceptional situations.
Another option is to return a pair std::pair<bool, int>. Some people love it, some people hate it.
My preference would be bool attemptGetValue(int& outValue). You return false if there's an error, in which case you don't touch outValue. Your return true otherwise and modify outValue
You can also use std::optional, but old timers might not be familiar wiht it.
Other than throwing an exception, returning a std::optional, or a std::pair, there is a precedent here: std::string::npos is normally set to a particularly large std::string::size_type value, normally -1 (wrapped around of course) and is used by some std::string functions to indicate a failure.
If you're willing to give up one legitimate return value then you could do something similar in your case. In reality though, typical (perhaps all) strings will be significantly smaller than npos; if that's not the case for you then perhaps one of the alternatives already mentioned would be better.
I have the following enumerator and it's likely to be expanded over the course of program development:
enum myEnum {
Element1,
Element2,
Element3
...
ElementX
Last
};
I have a function that uses the enumerator in the following way:
bool CheckEnumValidity(myEnum a)
{
bool valid = false;
switch (a) {
case Element1:
case Element2:
case Element3:
case ...
case ElementX:
valid true;
break;
case Last:
valid false;
break;
};
return valid;
}
QUESTIONS:
1) I duplicate Element1, Element2 etc. in two places in my program. How to get rid of the duplication in the safest way?
2) Should I have default behavior that throws an exception (or return false) in the aforementioned switch statement given that CheckEnumValidity() has an argument of myEnum type?
NOTES:
C++ 11 is unavailable for my application.
Provided that your enum really doesn't contain any explicit value assignment then you can write:
if (a <= Last) {
return (a < Last);
} else {
throw AnyExceptionYouWant();
}
It would probably be easier, through coding guidelines, peer pressure, policy enforcement (sack any programer who does not comply with the coding guideline) or other means to ensure that calling code which uses your enum only ever supplies named values.
In other words, disallow conversion of an integral value to an enumerated type. After all, doing such things negates most of the reason for using an enumerated type in the first place.
If, despite this suggestion, you want to test, I'd write a little program that parses your header files, finds all the enum types, and automatically generates your SomeFunction(). With makefiles, it is easy to ensure that program is run whenever relevant header files change, which means the function would be updated, recompiled, and linked into your program to keep the check consistent with the type definition.
As to whether your check function should throw an exception, that comes down to what the consequences of a value failing the test are. If your program should really not continue, then throw an exception. If the error is benign and your program can continue somehow, simply log an error message (e.g. to std::cerr) and continue.
To answer your first question, there is no very straightforward way to do this in C++, though I will leave a comment by your question pointing to some approaches.
For your second question, I recommend you use a default case. Here is why. The first reason is weaker, but the last two are stronger.
Someone may convert an integer explicitly to an enumerated value without checking that it is valid. This should be forbidden, but it still sometimes happens, and you should catch this programming error at run time if it was missed in code review.
You may read a struct or other data from an untrusted external source, where that struct contains an enum field, and forget to properly validate it. The untrusted external source could even be a file saved with an older version of your program, where the enum had a different set of valid values.
You may have an uninitialized enum somewhere.
Even something as simple as this:
enum A {X = 1, Y, Z};
int main()
{
A foo;
switch (foo) {
case X: return 0;
case Y: return 1;
case Z: return 2;
}
}
As to what you should do in the default case, it depends on your project and the specific enum. For example, if enums should always be validated before entering the bulk of your program, thus preventing invalid values, and it's okay to fail if this is violated, then you should probably throw an exception or even call exit, after printing a suitable error message – this is a programming failure caught at run time.
If failing like this is not an option, you should probably at least still try to log it, at least in a debug build, so you can detect the problem.
If invalid values make sense for a particular enum, then handle it as you see fit for that enum according to why it makes sense.
I am exploring the possibility of creating a Clutter binding for the D
language ( http://d-programming-language.org/) and have started by
trying some simple tests using dynamic loading of libclutter. I've run
into a problem that might derive from the GObject inheritance
system, and I'd appreciate any help getting it figured out. Here's the
rundown: using clutter_stage_get_default returns a ClutterActor* which
I can use with the clutter_actor_* methods. But I always get errors or
segfaults when I use the clutter_stage_* or clutter_container_*
methods. Here's my test code: http://pastebin.com/nVrQ69dU
At the clutter_container_add_actor call on line 56, I get the following error:
(<unknown>:11976): Clutter-CRITICAL **: clutter_container_add_actor:
assertion 'CLUTTER_IS_CONTAINER (container)' failed
In example code, I have noticed the CLUTTER_STAGE and
CLUTTER_CONTAINER macros for casting (these obviously are not
available to me), but as far as I could tell, they simply performed
some checks, then did a plain C cast. If this is incorrect, and some
Gobject type magic needs to be done on the stage pointer before
casting, please let me know. Binding and using the
clutter_stage_set_title or clutter_stage_set_color with cast(ClutterStage*)stage resulted in
segmentation faults, presumably the same issue.
EDIT: Here's a stripped down example with no external dependencies (if you're not on Linux, you'll need to replace the dl calls with your OS's equivalents). This code fails with a segfault, which according to GDB and Valgrind, is in clutter_stage_set_title (in /usr/lib/libclutter-glx-1.0.so.0.600.14)
The problem is that you don't declare the C functions as extern(C). Because of that dmd thinks you're calling a D function and uses the wrong calling convention. One way to do this correctly is like this:
alias extern(C) void function(void*, const char*) setTitleFunc;
auto clutter_stage_set_title = getSym!(setTitleFunc)("clutter_stage_set_title");
I'm not sure how to make it work without the alias though. DMD refuses to parse anything with extern(C) in a template parameter:
auto clutter_stage_set_title = getSym!(extern(C) void function(void*, const char*))("clutter_stage_set_title"); //Doesn't work
BTW: Your cstring function is dangerous: It returns a char* indicating that the string can be modified, but this is not always true: If you pass a string literal to toStringz it might not allocate new memory but return the pointer of the original string instead. String literals are in readonly memory, so this could lead to problems.
You could just adjust your function types to match the C Types (const gchar* in C --> const char* in D) and use toStringz directly.
structs in D cannot inherit from each other and casting struct pointers will return null unless there's a intermediate cast to void* (unlike a C cast) I got refuted here
you're better off adding another abstraction layer using handle-wrapping structs and emulating the checks from those macros when casting
but what happens if you do
clutter_container_add_actor(cast(ClutterContainer*)(cast(void*)stage), textbox);
(casting to void* first and then to ClutterContainer*)
I'm trying to convert a double to float as well as various integer types inside a dll, which is used as a Game Maker extension. I don't need a sensible result if the double doesn't fit the range of the target types, so I simply used a static_cast.
Everything works as intended when I call this code from my own test C++ application, but when it's called from Game Maker, range errors raise SIGFPE for some reason, which leads Game Maker to terminate my program with an error message.
I don't need sensible results for out-of-range conversions, but crashing is a no-no. I tried using llround instead of a cast, but it also raises the signal.
I also tried catching the signal myself by using signal(SIGFPE, SIG_IGN); right before the conversion, but it didn't change the behaviour at all. Maybe the ominous comment in the mingw signal.h has something to do with that: "SIGFPE doesn't seem to work?"
I checked the source code of a different dll used in a Game Maker extension, and the binary provided by the author performs simple cast conversions without a problem. When I compile the source myself however, the SIGFPE problem is present again. I am guessing that the author used a different compiler, but I'd prefer to stay with mingw if possible.
So, how do I either perform these conversions safely, or prevent the signal from being generated when I perform them with a simple cast? I'm using mingw-g++ 4.5.0 to compile at the moment.
Here's the function where the problem happens:
template<typename ValueType>
static double writeIntValue(double handle, double value) {
boost::shared_ptr<Writable> writable = handles.find<Writable>(handle);
if(writable) {
// Execution reaches this point
ValueType converted = static_cast<ValueType>(value);
// Execution doesn't reach this point if e.g. ValueType
// is short and value is 40000
writable->write(reinterpret_cast<uint8_t *>(&converted), sizeof(converted));
}
return 0;
}
The good solution is to perform the conversion correctly by ensuring that the source value is within the range of the target type before casting. So my code from the question could be corrected like this:
ValueType converted;
if(value >= std::numeric_limits<ValueType>::max()) {
converted = std::numeric_limits<ValueType>::max();
} else if(value <= std::numeric_limits<ValueType>::min()) {
converted = std::numeric_limits<ValueType>::min();
} else {
converted = static_cast<ValueType>(value);
}
Another option is to use numeric_cast from the Boost libraries, which throws an exception if the source value is out of range, so it has defined behaviour for all conversions.
The documentation of the Boost Numeric Conversion library contains some helpful information about how the standard defined certain conversions.
Thanks to rve for providing the correct suggestion in his answer, but unfortunately his example code is flawed, and I wanted to add some additional pointers that helped me.
Since you are using a DLL, are you sure the DLL is compiled in the same way as the program expects it? Maybe some 32/64 bit mismatch?
Also, SIGFPE can also be raised when there is an under/overflow when converting.
You can enable/disable the signal raised by this overflow by setting the mask using _FPU_SETCW (it's in fpu_control.h) My guess is that Game Maker enables this and your test program not.
I never tried this and I'm not sure mingw also has this but I hope this helps a little.
edit:
Why not making sure an overflow does not happen?
Something like:
if (value > std::numeric_limits<ValueType>::max())
{
value = std::numeric_limits<ValueType>::max();
}
else if (value < std::numeric_limits<ValueType>::min())
{
value = std::numeric_limits<ValueType>::min();
}
ValueType converted = value;
probably it's not related with conversion itself but with trying to access invalid memory (maybe stack corruptions or something like that). can you provide some code snippet?