How to overcome warning about functioni argument being const in vala? - vala

Vala code warning about a function expecting a non-const argument but being given const.
Vala code:
Gtk.TreeSelection treeSelection = treeview.get_selection();
Gtk.TreeModel treeModel = treeview.get_model();
List<Gtk.TreePath> treePaths = treeSelection.get_selected_rows(out treeModel);
Gtk.TreeIter treeIter;
List<Gtk.TreeRowReference> treeRowRefs = new List<Gtk.TreeRowReference>();
foreach (unowned Gtk.TreePath treePath in treePaths) {
treeRowRefs.append(new Gtk.TreeRowReference(treeModel, treePath));
}
foreach (unowned Gtk.TreeRowReference treeRowRef in treeRowRefs) {
if (treeModel.get_iter(out treeIter, treeRowRef.get_path())) {
fileListStore.remove(treeIter);
}
}
vala compiler warning:
warning: passing argument 1 of ‘gtk_tree_row_reference_get_path’ discards ‘const’ qualifier from pointer target type [enabled by default]
_tmp17_ = gtk_tree_row_reference_get_path (_tmp16_);
In file included from /usr/include/gtk-3.0/gtk/gtkcombobox.h:26:0,
from /usr/include/gtk-3.0/gtk/gtkappchooserbutton.h:29,
from /usr/include/gtk-3.0/gtk/gtk.h:42,
from /home/user/syswrite/syswrite.vala.c:9:
/usr/include/gtk-3.0/gtk/gtktreemodel.h:267:22: note: expected ‘struct GtkTreeRowReference *’ but argument is of type ‘const struct GtkTreeRowReference *’
GtkTreePath *gtk_tree_row_reference_get_path (GtkTreeRowReference *reference);
How to overcome this warning?

Per this answer, you're not doing anything wrong, it's just the C compiler doesn't have as much information as the vala compiler does, and hence complains about some of the C code that valac generates.

Related

A value of type 'num' can't be assigned to a variable of type 'int'

I am getting error : "A value of type 'num' can't be assigned to a variable of type 'int'."
while executing this code. I got the fix. Just wanted to know why this error. Also Do we need to add "!" for every variable operation?
void main() {
Map <int, int> val = {1:10};
int k = val[1]+5;
//int k = val[1]!+5; //fix
}
o/p dart pad:
Error compiling to JavaScript:
Info: Compiling with sound null safety
Warning: Interpreting this as package URI, 'package:dartpad_sample/main.dart'.
lib/main.dart:3:17:
Error: Operator '+' cannot be called on 'int?' because it is potentially null.
int k = val[1]+5;
^
lib/main.dart:3:17:
Error: A value of type 'num' can't be assigned to a variable of type 'int'.
int k = val[1]+5;
^
Error: Compilation failed.
Just put a not null operator (!) in line 3 as shown
void main() {
Map <int, int> val = {1:10};
int k = val[1]!+5;
print(k);
}
no issue was raised during execution, please lmk if the issue is still faced.

What literal expression has type `void`?

In Zig 0.9, I need a literal expression that has type void, for use as the context parameter to std.sort.sort, so that my lessThan function signature is semantically accurate. Is there some?
I tried these but to no avail:
const ek = #import("std").io.getStdOut().writer();
test "void" {
const kandidati = .{ type, u0, .{}, void, null, undefined };
inline for (kandidati) |k|
try ek.print("{}, ", .{#TypeOf(k)});
try ek.print("\n", .{});
}
giving
Test [0/1] test "void"... type, type, struct:31:37, type, #Type(.Null), #Type(.Undefined),
All 1 tests passed.
I don't want to use a dummy variable like const v: void = undefined;; that's too verbose.
For reference, using void as the context parameter to std.sort.sort with a lessThan function that takes a parameter of type void, gives an error message like
error: expected type 'fn(type,anytype,anytype) anytype', found 'fn(void, Type1, Type1) bool'
The expressions void{}, #as(void, undefined), and {} have type void, for example. You can see {} used in the standard library test cases for std.sort.sort.
The "canonical" way of getting the void value is to use an empty block.

How to assign a constant value as default value in constructor

class Foo {
final int x;
Foo([this.x = defValue]); // Compile-time error
static get defValue => 10;
}
Error:
The default value of an optional parameter must be a constant.
defValue is a compile time constant, so I should be able to pass its value to the constructor.
The expression defValue is not a compile-time constant expression. Evaluating it requires executing the getter to get a value, and constant evaluation cannot execute getters or methods (except a very specific list of allowed platform methods, like int.operator+). It might be that the expression returned by executing the defValue getter is itself a compile-time constant expression, but it's being returned through a non-constant operation.
Change the defValue definition to
static const defValue = 10;
then it should work. Reading constant declarations is a compile-time constant operation.
You refer to the docs saying that you can use a static method as a compile-time constant. That is correct, but that's the method itself which is the constant, you are still not allowed to call it.
That is:
static int foo(int x) => x;
static const fooRef = foo; // valid!
works because referencing the foo function value is a constant expression.
A getter is not a method, and you cannot do a "tear-off" of the getter. When you refer to it, you need to execute its body, and that's not allowed in a constant context.
My guess is that defValue is not known at compile time (since it's a getter and not a constant), so you should either use a constant variable like static const int defValue = 10 or initialize the class like this:
class Foo {
final int x;
Foo([int x]) : this.x = x ?? defValue;
static get defValue => 10;
}

Objective-C cast a block type into another got unexpected result

typedef (void (^blockType)());
I need cast blocks with different argument types into a same type blockType, and invoke it as the original type later. But there is a issue while casting block type.
The following code works well with any argument type, ...
((blockType)^(BOOL b) {
NSLog(#"BOOL: %d", b);
})(YES); // >> BOOL: 1
((blockType)^(int i) {
NSLog(#"int: %d", i);
})(1); // >> int: 1
((blockType)^(double f) {
NSLog(#"double: %f", f);
})(1.0 / 3); // >> double: 0.333333
((blockType)^(NSString *s) {
NSLog(#"NSString *: %#", #"string");
})(1.0 / 3); // >> NSString *: string
except float:
((blockType)^(float f) {
NSLog(#"float: %f", f);
})(1.0f); // >> float: 0.000000
((blockType)^(float f) {
NSLog(#"float: %f", f);
})(1.0f / 3); // >> float: 36893488147419103232.000000
but it is ok without casting:
(^(float f) {
NSLog(#"float without casting: %f", f);
})(1.0 / 3); // >> float without casting: 0.333333
how to explain and resolve it?
It appears to be a taint of the good old C language. Consider the following code (we can say it is kind of 'translation' of your Obj-C block with issues to C as far as blocks are related to function pointers (see here)):
void test()
{
void (*pEmpty)();
pEmpty = functionFloat;
pEmpty(1.0f / 3);
}
void functionFloat(float f)
{
printf("float: %f", f);
}
If you call test you will see the same result as when you invoke your 'sick' block. Compiler will provide just a warning about incompatible pointers and will let you run. But if you change
void (*pEmpty)();
to
void (*pEmpty)(void);
there will be a compile-time error. Same will happen if you add void explicitly to your void-blocks, e.g. (void (^)(void) instead of (void (^)().
The reason for such behavior explained in the C Standard:
The empty list in a function declarator that is not part of a
definition of that function specifies that no information about the number or types of the
parameters is supplied.§6.7.6.3-14 (p.134)
Thus, as it doesn't mean that there are no parameters but rather no info about them, cast passes fine.
The problem with unexpected output is the following:
A pointer to a function of one type may be converted to a pointer to a function of another
type and back again; the result shall compare equal to the original pointer. If a converted
pointer is used to call a function whose type is not compatible with the referenced type,
the behavior is undefined.§6.3.2.3-8 (p.56)
and
If the function is defined with a type that is not compatible with the type (of the
expression) pointed to by the expression that denotes the called function, the behavior is
undefined.§6.5.2.2-9 (p.82)
So, it seems that the solution here is just like #jtbandes said: don't mess block types and re-design this part of code to avoid such casts.
Explain: Calling the block as blockType- (void (^)()), the block is treated as (void (^)(double)).
Resolve: Must cast the block back to (void (^)(float)) when invoking.

How to test for type using a Type variable?

Is it possible to test the type of an object in Dart using an instance of Type stored in a variable? e.g.
Foo foo = new Foo();
Type testtype = Foo;
if (foo is testtype) {
print("foo matched testype");
}
This gives me the following warning:
The name 'testtype' is not a type and cannot be used in an 'is' expression
Is there a way of doing this?
Ultimately I want to pass the Type into a function as a parameter which then performs the "is" type test using this.
Foo foo = new Foo();
Type testtype = Foo;
if (foo.runtimeType == testtype) {
print("foo matched testype");
}
If (foo.runtimeType == testtype.runtimeType)

Resources