The compiler keeps whining about the need of a constant for the case type in a switch(){...}. But I have provided a freaking constant. - sorry, /rant mode off
Up in my class I have defined the type plus the TYPE_BULLISH and TYPE_BEARISH constants of the int types. Then I assigned values:
static const int TYPE_BULLISH = 0x001;
static const int TYPE_BEARISH = 0x002;
And I assigned the variable type a value of:
type = TYPE_BULLISH;
Then in the constructor
switch(type) {
case TYPE_BULLISH: Print("Bullish"); break;
case TYPE_BEARISH: Print("Bearish"); break;
default: Print("Doji");
}
Output error:
'TYPE_BULLISH' - constant expression required
Q1: Any idea what is going on here?
I mean, Q2: I provided a constant, right?
Try to use #define instead (note: No ; at the end of #define):
#define TYPE_BULLISH 0x001
#define TYPE_BEARISH 0x002
int type = TYPE_BULLISH;
switch(type) {
case TYPE_BULLISH: Print("Bullish"); break;
case TYPE_BEARISH: Print("Bearish"); break;
default: Print("Doji");
}
A2: No, you have not provided a constant.A1: Your MQL4 code is syntactically wrong and cannot get compiled.
While #JosephLee has provided a error-avoiding substitute, the problem is hidden in a way, MQL4-code retains a scope-of-validity
Your class-level designations cease to exist outside the container, where these have been declared / initialised.
Your code, outside of such container ( typically the inner-most surrounding { ... }-code block / hierarchy-level, where such a declaration took place ) simply cannot get compiled, as the compiler obeys the rules of scope-of-validity during the source-code parsing.
Q.E.D.
One may use "globally"-visible variables in case of a need for such centrally managed predefined constants.
Beware, that #include, #import, #property library and #export introduce more havoc into this circus.
You were warned, at least...
A use of a utility-function:
Example code how to use it from one library project:
Related
I'm a bit confused about the implications of the using declaration. The keyword implies that a new type is merely declared. This would allow for incomplete types. However, in some cases it is also a definition, no? Compare the following code:
#include <variant>
#include <iostream>
struct box;
using val = std::variant<std::monostate, box, int, char>;
struct box
{
int a;
long b;
double c;
box(std::initializer_list<val>) {
}
};
int main()
{
std::cout << sizeof(val) << std::endl;
}
In this case I'm defining val to be some instantiation of variant. Is this undefined behaviour? If the using-declaration is in fact a declaration and not a definition, incomplete types such as box would be allowed to instantiate the variant type. However, if it is also a definition, it would be UB no?
For the record, both gcc and clang both create "32" as output.
Since you've not included language-lawyer, I'm attempting a non-lawyer answer.
Why should that be UB?
With a using delcaration, you're just providing a synonym for std::variant<whatever>. That doesn't require an instantiation of the object, nor of the class std::variant, pretty much like a function declaration with a parameter of that class doesn't require it:
void f(val); // just fine
The problem would occur as soon as you give to that function a definition (if val is still incomplete because box is still incomplete):
void f(val) {}
But it's enough just to change val to val& for allowing a definition,
void f(val&) {}
because the compiler doesn't need to know anything else of val than its name.
Furthermore, and here I'm really inventing, "incomplete type" means that some definition is lacking at the point it's needed, so I expect you should discover such an issue at compile/link time, and not by being hit by UB. As in, how can the compiler and linker even finish their job succesfully if a definition to do something wasn't found?
I see in examples this code:
if (obj is User) { // do something }
I want to check the type of the object in a switch/case flow, and found a property .runtimeType of the object:
switch (obj.runtimeType) {
case User:
print(obj);
break;
}
Is this a correct way to check the type of the object?
There is no support in the Dart switch statement for switching by type.
You should use a sequence of if tests instead:
if (obj is User) {
print(obj);
} else if (obj is ...) ...
I really, really recommend that you never use runtimeType for anything.
It can be used to reflect, using dart:mirrors, on the type of an object (but you can also just use reflect(object) to reflect on the object itself). Apart from that, using runtimeType almost always causes otherwise avoidable problems.
The only thing you can do with the Type object returned by runtimeType is to check it for equality. If you do that (like in the switch above), then you don't correctly handle subtypes. If you ever have a subtype of User in your system, like if User is an interface and the implementation class is different, or if you mock a User for testing, or any number of other causes, then the instance will not have User as runtimeType, and the code won't recognize it.
Or maybe it will, because runtimeType can be overridden by the user, and any class can choose to return User. Testing against runtimeType isn't a guarantee that the class is actually the one you check for.
When you compare for type, you should always use is because it correctly handles subclasses.
Subtype substitutability is one of the core ideas of object oriented programming, so you could say that if you use runtimeType, you are probably not doing an optimal OO design.
(There are cases where code uses other.runtimeType == MyClass in operator== to avoid being equal to a subclass instance to avoid the "ColorPoint" problem - but it means that it's impossible to make a subclass or interface implementation (which includes mocks) of that type and have it pass equality checks. That's a very subtle restriction that I would avoid in shared library code. What you do in your own application, that nobody else will depend on, is at least only your problem :smile:).
switch string works.
switchType(Object object) {
switch (MirrorSystem.getName(new Symbol(object.runtimeType.toString()))) {
case "Animal":
print('animal basic');
break;
case 'Cat':
print('Mouse for cat');
break;
}
}
switch (obj.runtimeType.toString()) {
case 'User':
print(obj);
break;
}
You can create a condition beforehand. Here is an example, as I bumped into this too:
String grade;
if(grade is String) {
grade = grade;
} else {
grade = null.toString();
}
switch(grade) {
case "A":
print("Good");
break;
case "B":
print("Nice");
break;
case "null":
print("Type a string");
break;
default:
print("failed");
break;
}
This way you can check if a value is present or it is an empty string. As mentioned above the easy part is to use a simple If - Else, but otherwise use this.
I am trying to make some reusable blocks for my application.
CommonBlocks.h
void (^testBlock)(int) = ^(int number) {
// do nothing for now;
};
VariousImplementationFile.m
#import "CommonBlocks.h"
(void)setup {
testBlock(5);
}
Unfortunately, when I try to push this code to iOS device I receive error: linker command failed with exit code 1 (use -v to see invocation). It seems that I missing some.
Any advice?
Thanks
You try add static keyword before the declaration:
static void (^testBlock)(int) = ^(int number) {
// do nothing for now;
};
Your code causes error because you have non-static variable testBlock declared in .h header file.
When you call #import "CommonBlocks.h" in VariousImplementationFile.m, testBlock is declared once. Then you import CommonBlocks.h in some where else, testBlock is declared once more, so you'll get symbol duplicate error.
Declare block in CommonBlocks.h this way
typedef void (^RCCompleteBlockWithResult) (BOOL result, NSError *error);
Then you may use in any method for example:
-(void)getConversationFromServer:(NSInteger)placeId completionBlock:(RCCompleteBlockWithResult)completionBlock
This is not specific to blocks. Basically, you want to know how to have a global variable that is accessible from multiple files.
Basically, the issue is that in in C, each "symbol" can only be "defined" once (it can be "declared" multiple times, but just be "defined" once). Thus, you cannot put the "definition" of a symbol in a header file, because it will be included in multiple source files, so effectively, the same symbol will be "defined" multiple times.
For a function, the prototype is declaration, and the implementation with the code is the definition. You cannot implement a function in a header file for this reason. For a regular variable, writing the name and type of the variable is defining it. To only "declare" it, you need to use extern.
It is also worth mentioning static. static makes a variable local to a particular source file. That way, its name won't interfere with variables with the same name elsewhere. You can use this to make global variables that are "private" to a particular file. However, that is not what you are asking for -- you are asking for the exact opposite -- a variable that is "public", i.e. shared among files.
The standard way to do it is this:
CommonBlocks.h
extern void (^testBlock)(int); // any file can include the declaration
CommonBlocks.m
// but it's only defined in one source file
void (^testBlock)(int) = ^(int number) {
// do nothing for now;
};
Dart has the concept of compile-time constants. A compile-time constant is parsed and created at compile time, and canonicalized.
For example, here is a const constructor for Point:
class Point {
final num x, y;
const Point(this.x, this.y);
}
And here's how you use it:
main() {
var p1 = const Point(0, 0);
var p2 = const Point(0, 0);
print(p1 == p2); // true
print(p1 === p2); // true
}
This is a non-obvious feature, with seemingly no parallels to features in other dynamic languages. There are restrictions on const objects, like all fields must be final and it must have a const constructor.
Why does Dart have compile-time constants?
From the mailing list, Florian Loitsch writes:
The canonicalization property of compile-time constants is nice, but
not the main-reason to have them. The real benefit of compile-time
constants is, that they don't allow arbitrary execution at
construction and can therefore be used at places where we don't want
code to executed. Static variables initializers, for example, were
initially restricted to compile-time constants to avoid execution at
the top-level. In short, they make sure that a program starts with
'main' and not somewhere else.
Lasse's answer here helped me a lot
So, what are compile-time constants good for anyway?
They are useful for enums.
You can use compile-time constant values in switch cases.
They are used as annotations.
Compile-time constants used to be more important before Dart switched
to lazily initializing variables. Before that, you could only declare
an initialized global variable like "var x = foo;" if "foo" was a
compile-time constant. Without that requrirement, most programs can be
written without using any const objects
I'm working on some ActionScript code that needs to juggle a bunch of similar-but-not-interchangeable types (eg, position-in-pixels, internal-position, row-and-column-position) and I'm trying to come up with a naming scheme to minimize the complexity.
Additionally, I don't yet know what the best format for the "internal position" is – using int, uint and Number all have advantages and disadvantages.
Normally I'd solve this with a typedef:
typedef float pixelPos;
typedef int internalPos;
typedef int rowColPos;
Is there any way of getting similar functionality in ActionScript?
If you're using Flex or another command-line compiler to build your project, you could add a pass from an external preprocessor to your build process.
Doesn't get the type-safety, but otherwise appears to do what you want.
I have found an article titled Typedefs in ActionScript 3, which suggests using:
const pixelPos:Class = int;
But that doesn't work – the compiler complains that "Type was not found or was not a compile-time constant: pixelPos" (note: this also happens when I use Object instead of int).
Here is an example of code which doesn't compile:
const pixelPos:Class = int;
function add3(p:pixelPos):void { // <-- type not found on this line
return p + 3;
}
Just make it static const and you can register your own class. Like this:
static const MyClass:Class = int;
And you can't make a variable with this type:
var ert:MyClass; //error
private function ert2():MyClass {}; //error
But you can make an instance:
var ert:* = new MyClass();