for
class Y
def initialize(#a : String)
end
getter a
end
class X
macro test(name)
#{{name}} = y.{{name}}
end
#a : String
def initialize(y : Y)
test a
end
end
I got
instance variable '#a' of X was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported.
why? and set #a to nil did solve the problem but that's not a good workaround in my opinion.
Is it a bug, a design limit or just I'm not doing the right thing?
Yes, currently this is a design limitation. Quoting Ary from https://github.com/crystal-lang/crystal/issues/2731
Yes, this is expected behaviour. initialize must be simple enough for the compiler to analyze. A macro might be redefined in a subclass so resolving init is not trivial for a first pass.
This is a "won't fix" for me, or maybe we can mark it as an enhancement, but it won't happen soon (maybe never)
There's a hack I introduced to make initialization via macro possible: if {{#type}} is mentioned then the compiler will lazily check the method on call. It's not documented, though. And it has several bugs. But for now it might be okay.
Related
Is it possible to do a compile-time-assertion that a function get called at least one occurrence?
It is not related to how many times the function is executed.
//C.h
class C{ //Callee
void f();
};
//C.cpp
void C::f(){ //note: non static
assert_called_at_least_once(); //<--- I expected something like this $$
............. some complex thing ......
}
//D.cpp
D::f2(){ //Caller
C c;
if(false){
//^ This line is to emphasize that I don't care whether c.f() will be executed
c.f(); //<--- if I comment out this line, an error should occur.
//( Assume that it is only one occurrence of C::f(). )
}
}
It is for debugging purpose.
Edit
As requested, I will provide more information why I want this feature.
My game has many sub-systems. C is one of them.
I want to make sure that my game calls a certain function in a certain sub-system (e.g. Bullet System updates bullet's position) at least once.
Here is the reason.
Sometimes, when I want to narrow the scope that a bug can occur, I disable the function by commenting out this line in my big System (D) :-
bulletSystem->update();
After the bug is found, I sometimes forgot to re-enable it back.
In some cases, it is easier if I can insert an assert line inside the function rather than set breakpoint.
Edit2:
I prefer a solution explaining about C++ feature rather than a solution to solve my specific example about game.
If such solution simply does not exist (suggested by M.M and n.m.), please post as an answer, so I can sadly accept it.
Edit3:
#define #ifdef ... (suggested by rezdm)
or other # seem to be useful.
However, I demand a solution that
- the $$-line is replaced by <= 1 line of simple code, because more complexity = more bugs
- does not require any modification in caller (D)
Based on a poorly stated and recently deleted SO question ("Is it possible to call a function without calling it?") I have a similar question, hopefully put in a more logical perspective.
Is it possible / what are the best practices, to disable a function call from a codebase ? By disabling I don't mean greping through the whole code to manually comment out the function (which is a valid but somewhat tedious task). The only ways I can think of are
Returning as soon as entering function
ret_type foo()
{
return ret_type();
// actual implementation is not allowed to run
}
which would be a bit dangerous when the return code is used by caller functions.
Replace the declaration with an idle macro
ret_type foo();
#define foo() do { void; } while (0);
Is there a standard way, maybe a compiler hook, a pragma directive to do this and if not what are some other ways?
Is there a standard way, maybe a compiler hook, a pragma directive to do this and if not what are some other ways?
Let's just think for a minute, together. Let's consider two main cases:
the function returns void
the function returns something
In the first case you can simply take the body of the function and comment it out. BOOM: disabled.
In the second case you have a return value. Let's consider other two cases:
the returned value is used
the returned value is not used
In the first case you should ask yourself: can I return a dummy value and get away with it? If the answer is yes, then do so. If not, then you can't do anything about it except refactor your entire code.
In the second case you can comment it out, but why you are returning a value in the first place.
I have the following code in Lua:
ABC:
test (X)
The test function is implemented in C + +. My problem is this: I need to know what the variable name passed as parameter (in this case X). In C + + only have access to the value of this variable, but I must know her name.
Help please
Functions are not passed variables; they are passed values. Variables are just locations that store values.
When you say X somewhere in your Lua code, that means to get the value from the variable X (note: it's actually more complicated than that, but I won't get into that here).
So when you say test(X), you're saying, "Get the value from the variable X and pass that value as the first parameter to the function test."
What it seems like you want to do is change the contents of X, right? You want to have the test function modify X in some way. Well, you can't really do that directly in Lua. Nor should you.
See, in Lua, you can return values from functions. And you can return multiple values. Even from C++ code, you can return multiple values. So whatever it is you wanted to store in X can just be returned:
X = test(X)
This way, the caller of the function decides what to do with the value, not the function itself. If the caller wants to modify the variable, that's fine. If the caller wants to stick it somewhere else, that's also fine. Your function should not care one way or the other.
Also, this allows the user to do things like test(5). Here, there is no variable; you just pass a value directly. That's one reason why functions cannot modify the "variable" that is passed; because it doesn't have to be a variable. Only values are passed, so the user could simply pass a literal value rather than one stored in a variable.
In short: you can't do it, and you shouldn't want to.
The correct answer is that Lua doesn't really support this, but there is the debug interface. See this question for the solution you're looking for. If you can't get a call to debug to work directly from C++, then wrap your function call with a Lua function that first extracts the debug results and then calls your C++ function.
If what you're after is a string representation of the argument, then you're kind of stuck in lua.
I'm thinking something like in C:
assert( x==y );
Which generates a nice message on failure. In C this is done through macros.
Something like this (untested and probably broken).
#define assert(X) if(!(X)) { printf("ASSERION FAILED: %s\n", #X ); abort(); }
Here #X means the string form of the arguments. In the example above that is "x==y". Note that this is subtly different from a variable name - its just the string used in the parser when expanding the macro.
Unfortunately there's no such corresponding functionality in lua. For my lua testing libraries I end up passing the stringified version as part of the expression, so in lua my code looks something like this:
assert( x==y, "x==y")
There may be ways to make this work as assert("x==y") using some kind of string evaluation and closure mechanism, but it seemed to tricky to be worth doing to me.
EDIT:
While this doesn't appear to be possible in pure lua, there's a patched version that does seem to support macros: http://lua-users.org/wiki/LuaMacros . They even have an example of a nicer assert.
I've got a small bit of code from a library that does this:
#define VMMLIB_ALIGN( var ) var
template< size_t M, typename T = float >
class vector
{
...
private:
// storage
VMMLIB_ALIGN( T array[ M ] );
};
And you can call it by doing
//(vector<float> myVector)
myVector.array;
No parenthesis or anything.
what?
After reading the answers, it appears I should've done more looking. XCode's "Jump to Definition" gave me only one result. Searching the library gave me another:
#ifndef VMMLIB_CUSTOM_CONFIG
# ifndef NDEBUG
# define VMMLIB_SAFE_ACCESSORS
# endif
# define VMMLIB_THROW_EXCEPTIONS
# ifdef VMMLIB_DONT_FORCE_ALIGNMENT
# define VMMLIB_ALIGN( var ) var
# else
# ifdef __GNUC__
# define VMMLIB_ALIGN( var ) var __attribute__((aligned(16)))
# elif defined WIN32
# define VMMLIB_ALIGN( var ) __declspec (align (16)) var
# else
# error "Alignment macro undefined"
# endif
# endif
#endif
This offers different settings, depending on what system it's building for.
Regardless, thanks. Can't believe I got confused over a member access!
Ultimately, myVector.array refers to the array variable in the class, and variables don't need the function-calling notation ().
BTW / all-capital identifiers should only be used for preprocessor macros (as they are here). In this case, the macro VMMLIB_ALIGN must be being used to make it easier to later "enchance" the code generated for and alongside the array variable (e.g. prefixing it with static, extern, const, volatile or something compiler-specific) and/or adding some associated functionality such as get/set/search/clear/serialise functions that work on the array.
In general - when you're not sure what the macro is doing, you can get more insight by running the compiler with a command-line switch requesting preprocessor output (in GNU g++, the switch is -E)... then you'll be able to see the actual source code that the C++ compiler proper deals with.
EDIT - few thoughts re your comment, but too long to include in a comment of my own...
C++ classes are private until another access specifier is provided (but in practice the public interface is normally put first so the programmer still must remember to explicitly use private). structs are public by default. So, data is effectively exposed by default in the most common coding style. And, it doesn't need functional-call semantics to access it. Objective-C may well be better at this... your comment implies you use functional call notation for data members and functions, which is hidden by default? It's so good to have a common notation! In C++, the difficult case is where you have something like...
struct Point
{
double x, y;
};
...
// client usage:
this_point.x += 3 - that_point.y;
...then want to change to...
struct Point
{
double angle, distance;
};
...you'd need some pretty fancy and verbose manually-coded and not terribly efficient proxy objects x and y to allow the old client code to keep working unmodified while calculating x and y on the fly, and updating angle and distance as necessary. A unified notation is wonderful - allowing implementation to vary without changes to client source code (though clients would need to recompile).
maybe I'm oversimplying, but if you look at the #define macro it just writes the variable into the class.
So you have
class vector
{
...
T array[ M ];
};
after the expansion. So it's just a public variable on your class.
array is not a method, it's an array of type T of size M.
First, for the record, templates have nothing to do with this. There is no special interaction between the macro and the fact that your class is a template.
Second, going by the name of the macro, I'd guess it is meant to ensure alignment of a variable.
That is, to get an aligned instance x of a type X, you'd use VMMLIB_ALIGN(X x);
In practice, the macro does nothing at all. It simply inserts its argument, so the above results in the code X x; and nothing else.
However, it may be that the macro is defined differently depending on the hardware platform (since alignment requirements may vary between platforms), or over time (use a dummy placeholder implementation like this early on, and then replace it with the "real" implementation later)
However, it does seem pointless since the compiler already ensures natural alignment for all variables.
I have inherited a very long set of macros from some C algorithm code.They basically call free on a number of structures as the function exits either abnormally or normally. I would like to replace these with something more debuggable and readable. A snippet is shown below
#define FREE_ALL_VECS {FREE_VEC_COND(kernel);FREE_VEC_COND(cirradCS); FREE_VEC_COND(pixAccum).....
#define FREE_ALL_2D_MATS {FREE_2D_MAT_COND(circenCS); FREE_2D_MAT_COND(cirradCS_2); }
#define FREE_ALL_IMAGES {immFreeImg(&imgC); immFreeImg(&smal.....
#define COND_FREE_ALLOC_VARS {FREE_ALL_VECS FREE_ALL_2D_MATS FREE_ALL_IMAGES}
What approach would be best? Should I just leave well alone if it works? This macro set is called twelve times in one function. I'm on Linux with gcc.
Usually I refactor such macros to functions, using inline functions when the code is really performance critical. Also I try to move allocation, deallocation and clean up stuff into C++ objects, to get advantage of the automatic destruction.
If they are broken then fix them by converting to functions.
If they're aren't broken then leave them be.
If you are determined to change them, write unit-tests to check you don't inadvertently break something.
Ideally, I would use inline functions instead of using macros to eliminate function call overhead. However, basing from your snippet, the macros you have would call several nested functions. Inlining them may not have any effect, thus I would just suggest to refactor them into functions to make them more readable and maintainable. Inlining improves performance only if the function to be inlined is simple (e.g. accessors, mutators, no loops).
I believe this is your decision. If the macros are creating problems when debugging, I believe it is best to create some functions that do the same things as the macros. In general you should avoid complicated macros. By complicated I mean macros that do something more than a simple value definition.
Recommended:
// it is best to use only this type of macro
#define MAX_VALUE 200
The rest is not recommended (see example below):
// this is not recommended
#define min(x,y) ( (x)<(y) ? (x) : (y) )
// imagine using min with some function arguments like this:
//
// val = min(func1(), func2())
//
// this means that one of functions is called twice which is generally
// not very good for performance