Is there a clang flag to warn when you use e.g. an object in an if statement instead of a boolean expression?
I googled for this but couldn't find anything. This would help prevent mistakes like this, especially when using editor generated Core Data classes:
NSNumber *n = #(YES)
if (n) { // should be n.boolValue instead of n
...
}
I found an "Implicit Boolean Conversions" option in Xcode but that doesn't seem to be it (I double checked).
No, there is no short-hander for this and there cannot be.
A.
if comes from classical C. In classical C there is no boolean type. (They extended C in 99, but did not touch if.) Basically everything !=0 is true, everything ==0 is false.
B.
n is no object. It is an object reference. You need expressions like you have to check, whether the object reference points to nil. With your suggestion there would be no difference between "no object" and "an object containing NO".
Related
Is there a special name for doing assignment in a conditional? Here is an example of what I am asking about in C:
// Assume a and b have been previously defined and are compatible types
if( (a = b) ) { // <- What do you call that?
//do something
}
A couple friends of mine and I are convinced that there is a name for it, and some other people have agreed that there is one, but we can't find it anywhere. Has anyone here ever heard a term for it?
Assuming that an assignment is intentional, there is no special name for this. C language specification places a very weak requirement on the controlling expression of an if statement:
6.8.4.1-1: The controlling expression of an if statement shall have scalar type.
An assignment expression satisfies this requirement, as long as a and b are scalar. An implicit comparison to zero is performed on the result of this assignment:
6.8.4.1-2: In both forms, the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal to 0.
Note that compilers would issue a warning when they see an assignment like that, because missing second = is a common source of errors. You can prevent these warnings using parentheses, as described in this Q&A.
It doesn’t really have a name, though people do call it various things. If the code follows your question:
if( a = b )...
then common terms are: bug, error, etc. However if b is not a variable but an expression, e.g. as in the common C patterns:
if( (c = getchar()) != EOF )...
while( *q++ = *p++ )...
then it might be called an idiom, pattern, etc.
I don’t know if it has a name but I’d call it “useful feature that nobody understands”.
It is very useful indeed.
We can consider it a slang.
In C++ for example you can use this by declaring a variable directly, and this is useful for safety checks:
if (Object *a = takeObject()) {
// a is not nullptr
}
Or when I don’t want to repeat a statement in a loop:
while (a = next()) {
}
Instead of:
a = next();
while (a) {
a = next();
}
But commonly these are just mistakes which compilers like gcc and clang give warnings about (and they force you to put an horrible double tuple to silence the warning ew!).
I have been searching for this all over the web, but everything is either talking about the ErrObject class, or the constant vbError returned by the VarType function. I want to know what that type actually is, e.g. an integer is something like 4, a string is something like "hello world", etc.
For a little background, here is a link to the official MSDN page about VarType, which shows all the constants it returns and what they represent. What is Error value?
If you are familiar with COM in C/C++, you should know that from that perspective VarType() is a simple function that essentially extracts the value of the vt member from the Variant passed in as a parameter. The possible values of the vt member are documented in many places, such as here.
If you check inside of the COM system headers (e.g. WTypes.h distributed as part of in the Windows SDK), you will see that the VbError value of 10 indeed maps to the C/C++ enum value of VT_ERROR.
enum VARENUM
{ VT_EMPTY = 0,
...
VT_ERROR = 10,
...
} ;
The MSDN link above describes the meaning of a vt that equals VT_ERROR as follows:
An SCODE was specified. The type of the error is specified in scode.
Generally, operations on error values should raise an exception or propagate the error to the return value, as appropriate.
So, here's basically what it means:
A Variant obviously supports storing many types of values, and among them is the obscure possibility of storing an "Error Code". More correctly, these codes are formally called scode's, because they can indicate many types of "success" as well as "failures". Most people refer to these codes as HRESULTs.
These codes are the same kind of "Error Codes" that you get from Err.Number in VB6. So, you can tell a Variant to distinguish an "Error Code" from just a plain number.
In reality, few programs or COM components - if any - will ever put error codes in Variants. Almost everybody just issues COM Exceptions to communicate errors (this mechanism is exposed in VB6 via the Err object). Even those components that return error codes outside of the COM Exception mechanism, would likely do so in typed variables (e.g. Long's).
Therefore, the reason this possible return value exists is for completeness. You will almost never see it in real life.
(Edit: Remove bit about not being able to create an "Error" variant. #Joe proved me wrong on that. You can use CVErr() to create one)
In VB6 and VBA, error values are created by calling the CVErr function.
This function returns a Variant whose VarType is vbError, and for which the IsError function returns True.
A typical use case for this is an Excel UDF that returns a Variant: if you return an error value, it will display as #VALUE!.
What is the operator or function to test whether two variables of the same custom object type refer to the same object? I've tried
If myObject = yourObject Then
But get a runtime error 438 object doesn't support this property or method. I'm guessing that's telling me to override the '=' operator to test if all the fields of the two objects have the same value. But what I want is to test whether they are the same object.
I'm guessing that's telling me to override the '=' operator to test if all the fields of the two objects have the same value.
No, it tells you the objects don't have a default property which would have been called otherwise, and the returned results compared.
You test reference equality with Is
If myObject Is yourObject Then
You need to serialize the objects somehow and then compare attribute by attribute values. The "is" operator is as dumb as it gets, it only matches if another object is the same instance assigned to the compared variable.
I suggest using a jsonStringify library. I adapted one for my DexTools.xlam open source project https://github.com/dexterial/Dextools/tree/master/Main starting from the Parsing JSON in Excel VBA post. It has much more added features since I added quite a few other excel objects serialization/hashing options and it is made using the vba test driven development that DexTools incorporates. It is still work in progress so dont expect miracles
I'm learning D and have seen a lot of code like this:
ushort x = to!ushort(args[1]);
I assume this casts args[1] to ushort, but what's the difference between this and cast(ushort)?
EDIT: And what other uses does the exclamation mark operator have?
In D,
to!ushort(args[1])
is shorthand for the template instantiation
to!(ushort)(args[1])
and is similar to
to<ushort>(args[1])
in languages like C++/Java/C#.
The exclamation point is to note the fact that it's not a regular argument, but a template argument.
The notation does not use angle brackets because those are ridiculously difficult to parse correctly for a compiler (they make the grammar very context-sensitive), which makes it that much more difficult to implement a correct compiler. See here for more info.
The only other use I know about is just the unary 'not' operation (e.g. false == !true)... I can't think of any other uses at the moment.
Regarding the cast:
cast(ushort) is an unchecked cast, so it won't throw an exception if the value is out of range.
to!ushort() is a checked cast, so it throws an exception if the value is out of range.
The exclamation mark here is not an operator, it is just a token part of the explicit template instantiation syntax (described in detail here).
std.conv.to (docs) is a function template for converting between arbitrary types. It is implemented entirely in the library and has no special support in the language. It has a broader and different scope compared to the cast operator.
The to template takes two type parameters; a "to" type and a "from" type, in that order. In your example, the template is explicitly instantiated with the single type argument ushort for the "to" parameter, and a second type argument string (assuming args comes from the first parameter to main) is automatically inferred from the regular function argument passed to the function (args[1]) as the "from" parameter.
The resulting function takes a string parameter and returns a ushort parsed from that string, or throws an exception if it failed. The cast operator will not attempt this kind of high-level conversion.
Note that if there is more than one explicit template parameter, or that parameter has more than one token in it (ushort is a single keyword token), you must wrap the template parameter list in parentheses:
ushort result;
result = to!(typeof(result))(args[1]);
In this example, typeof, (, result and ) are four separate tokens and the parentheses are thus required.
To answer your last question, the ! token is also used for the unary not operator, unrelated to template instantiations:
bool yes = true;
bool no = !yes; // 'no' is false
You already got two excellent answers by jA_cOp and Merhdad. I just want answer directly to the OP question (what's the difference between this and cast(ushort)?) - The difference is that cast(ushort)args[1] will not work (you cannot cast from a string to an uint just like that), while the to!(type)(param) template knows what to do with the string and how to convert it to the primitive type.
I have a GUI app written in C++/CLI which has a load of configurable options. I have some overloaded functions which grab values from my data source and I'd like to connect my options to those values.
So here's a couple of data retrievers:
bool GetConfigSingle(long paramToGet, String^% str, char* debug, long debugLength);
bool GetConfigSingle(long paramToGet, bool^% v_value, char* debug, long debugLength);
I was hoping to pass in the checkbox's Checked getter/setter as follows:
result = m_dataSource->GetConfigSingle(CONFIG_OPTION1, this->myOption->Checked, debug, debugLen);
...but for some reason I get an odd compiler error which suggests the Checked value isn't being passed as I'd expect:
1>.\DataInterface.cpp(825) : error C2664: 'bool DataInterface::GetConfigSingle(long,System::String ^%, char*, long)' : cannot convert parameter 2 from 'bool' to 'System::String ^%'
Previously this code passed the checkbox in and modified the values itself, but I'm keen to break the dependency our data collection currently has on windows forms.
So what am I missing here?
[Edit] I've filled out the function definitions as they originally were to avoid confusion - my attempt to reduce the irrelevent information failed.
I'm fairly certain that the CheckBox getter / setter returns a bool.
Figured I'd clarify my comments from above and make it a "real" answer...
When you call Checked, what you're getting back as a return value is a bool that represents the current state of the CheckBox. It is not, however, a reference to the actual data member that holds the CheckBox's state. In fact, a properly encapsulated class shouldn't give access to it. Furthermore, since Checked returns a bool by value, that bool is a temporary object that doesn't necessarily exist by the time GetCongigSingle is called.
This leaves you with several options. Either pass the bools by value, and later set the CheckBox's state, or pass the CheckBox itself by reference and "check" it wherever you want.
The two overload of the method GetConfigSingleFile that you have mentioned both take two arguments whereas you are passing 4 arguments to the method. Are there any default arguments? If yes, can you please reproduce the original method declarations?
Most probably, the 4 argument overload of this method is expecting a String^% as the 2nd argument. This is what the compiler is suggesting anyway. But if we can have a look at the method declarations that could help diagnosing the problem.
This isn't an answer to my question, but worth being aware of - apparently there's a quirk in passing properties by reference.