Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

miscellaneous thoughts from PavelVozenilek #548

Closed
PavelVozenilek opened this issue Oct 19, 2017 · 25 comments
Closed

miscellaneous thoughts from PavelVozenilek #548

PavelVozenilek opened this issue Oct 19, 2017 · 25 comments
Labels
bug Observed behavior contradicts documented or intended behavior
Milestone

Comments

@PavelVozenilek
Copy link

This fails:

pub fn main() -> %void {
  var x: u4 = undefined;
  x = @truncate(u4, 9999);
}

with strange error:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:9:21: error: type '(integer literal)' has fewer bits than destination type 'u4'
  x = @truncate(u4, 9999);
                    ^

@PavelVozenilek
Copy link
Author

@sizeof doesn't seem to work at all:

const io = @import("std").io;
pub fn main() -> %void {
  %%io.stdout.printf("{}\n", @sizeOf(u16));
}

gives error:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:6:30: error: parameter of type '(integer literal)' requires comptime
  %%io.stdout.printf("{}\n", @sizeOf(u16));
                             ^


It is probably better to report 0.1.1 errors in one thread. Many previous issues have valuable discussions and flooding the tracker with every little problem would hide them.

@tiehuis tiehuis added the bug Observed behavior contradicts documented or intended behavior label Oct 19, 2017
@PavelVozenilek
Copy link
Author

PavelVozenilek commented Oct 19, 2017

Automatic structure packing does not seem to work optimally:


const io = @import("std").io;

const xxx = struct {
 b1 : u2,
 x : u8,
 b2 : u2,
 y : u8,
 b3 : u2,
 b4 : u2,
 z : u32,
};

pub fn main() -> %void {
  var sz : u32 = @sizeOf(xxx);
  %%io.stdout.printf("{}\n", sz);
}

Invoking it gives 12 instead of expected 8. Other combinations give higher size too.


Edit: it also fails with no less-than-byte members:

const io = @import("std").io;

const xxx = struct {
  m1 : u16,
  m2 : u8,
  m3 : u32,
  m4 : u8,
};

pub fn main() -> %void {
  var sz : u32 = @sizeOf(xxx);
  %%io.stdout.printf("{}\n", sz);
}

Gives 12, should 8.


Btw, I think this feature (automatic rearangement of structure members) is mistake, wrong and confusing. In addition keyword packed is applied on opposite feature.

I'd once suggested solution here:
#488 (comment)

@PavelVozenilek
Copy link
Author

Struct method cannot take non-const pointer. (Could be my misunderstanding.)

const xxx = struct {
  pub fn bar(self : &xxx) {}
};

pub fn main() -> %void {
  var x : xxx = undefined;
  x.bar();
}

fails with error:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:9:3: error: expected type '&xxx', found 'xxx'
  x.bar();
  ^

When I add const to the pointer (&const xxx) it compiles. But I feel that it should be possible to pass self as mutable pointer.

@PavelVozenilek
Copy link
Author

This compiles, in spite of struct method and struct member having the same name:

const xxx = struct {
  pub fn bar(self : &const xxx) {}
  bar : u8
};

pub fn main() -> %void {
}

But when I try to use the method it fails:

const xxx = struct {
  pub fn bar(self : &const xxx) {}
  bar : u8
};

pub fn main() -> %void {
  var x : xxx = undefined;
  x.bar();
}

with error:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:10:4: error: type 'u8' not a function
  x.bar();
   ^

Something feels wrong.

@andrewrk andrewrk added this to the 0.2.0 milestone Oct 19, 2017
@PavelVozenilek
Copy link
Author

printf also doesn't like i128 type. This program:

const io = @import("std").io;


pub fn main() -> %void {
  var sz : i128 = undefined;

  sz = @minValue(u16);
  %%io.stdout.printf("{}\n", sz);
  sz = @minValue(i16);
  %%io.stdout.printf("{}\n", sz);
}

compiled but when I run the result executable it crashes.

@PavelVozenilek
Copy link
Author

Zig requires initialization, even for empty structs:

const foo = struct {};

pub fn main() -> %void {

  var f : foo;
}

results in :

 
O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:11:3: error: variables must be initialized
  var f : foo;
  ^

While empty struct does not make much of sense, asking for its initialization is IMO error.

@PavelVozenilek
Copy link
Author

Docs states:

In Zig, structs, unions, and enums with payloads cannot be passed by value to a function.

However this compiles:

const foo = struct 
{
  x : i32,
  y : i32,
};

fn bar(f : foo) {}

pub fn main() -> %void {

  var f : foo = undefined;
  //bar(f);  // <<== it stops to compile when I uncomment this
}

This feels like a bug, the offending function has to be called for error to show.

@andrewrk
Copy link
Member

Zig requires initialization, even for empty structs:

Can you make a separate issue for this one? I have a clear answer for you, and I want to be able to direct other people to the issue.

@andrewrk
Copy link
Member

This feels like a bug, the offending function has to be called for error to show.

Same thing, can you make a separate issue? I have an answer and I want to be able to point back to the issue as a point of reference.

@PavelVozenilek
Copy link
Author

Example copy pasted from the documentation works:

pub fn main() -> %void {
 const a  = true;
 const b = false;

 const result = if (a != b) 47 else 3089;
}

If I switch to variables it fails:

pub fn main() -> %void {
 var a  = true;
 var b = false;

 var result = if (a != b) 47 else 3089;
}

I get:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:15:17: error: unable to infer expression type
 var result = if (a != b) 47 else 3089;
                ^

If I make only the result variable I get yet another strange error.

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:15:2: error: variable of type '(integer literal)' must be const or comptime
 var result = if (a != b) 47 else 3089;
 ^

This feels inconsistent and buggy.

@PavelVozenilek
Copy link
Author

Initialization of struct member does not allow to use previously initialized member. I tried:

const io = @import("std").io;

const foo = struct 
{
  x : i32,
  y : i32,
};


pub fn main() -> %void {


  var bar : foo = foo {
    .x = 10,
    .y = .x + 10,
  };


  %%io.stdout.printf("x = {}, y = {}\n", bar.x, bar.y);
}

and got error:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:15:10: error: invalid token: '.'
    .y = .x + 10,
         ^

Removing the leading dot didn't help.

@andrewrk andrewrk changed the title 0.1.1 @truncate miscellaneous thoughts from PavelVozenilek Oct 21, 2017
@PavelVozenilek
Copy link
Author

Possibly another problem with printf. I wanted to print pointer to a string argument.

This fails to compile:

const io = @import("std").io;

fn foo(comptime s: []const u8)
{
  var  ps : &const []const u8 = &s;
  %%io.stdout.printf("string = {}, ptr to string = {}\n", s, ps);
}

pub fn main() -> %void {
  foo("abc");
}

with error:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\lib\zig\std\fmt\index.zig:214:17: error: Unable to format type '&const []const u8'
                @compileError("Unable to format type '" ++ @typeName(T) ++ "'");
                ^
O:\zig0.1.1\lib\zig\std\fmt\index.zig:61:37: note: called from here
                    if (!formatValue(args[next_arg], context, output))
                                    ^
O:\zig0.1.1\lib\zig\std\io.zig:154:23: note: called from here
        _ = fmt.format(&context, printOutput, format, args);
                      ^
O:\zig0.1.1\lib\zig\std\io.zig:144:27: note: called from here
        %return self.print(format, args);
                          ^
O:\zig0.1.1\b.zig:9:21: note: called from here
  %%io.stdout.printf("string = {}, ptr to string = {}\n", s, ps);
                    ^
O:\zig0.1.1\b.zig:14:6: note: called from here
  foo("abc");
     ^
O:\zig0.1.1\lib\zig\std\fmt\index.zig:178:5: error: expected type 'bool', found 'void'
    switch (@typeId(T)) {
    ^
O:\zig0.1.1\lib\zig\std\fmt\index.zig:61:37: note: called from here
                    if (!formatValue(args[next_arg], context, output))
                                    ^
O:\zig0.1.1\lib\zig\std\io.zig:154:23: note: called from here
        _ = fmt.format(&context, printOutput, format, args);
                      ^
O:\zig0.1.1\lib\zig\std\io.zig:144:27: note: called from here
        %return self.print(format, args);
                          ^
O:\zig0.1.1\b.zig:9:21: note: called from here
  %%io.stdout.printf("string = {}, ptr to string = {}\n", s, ps);
                    ^
O:\zig0.1.1\b.zig:14:6: note: called from here
  foo("abc");

@PavelVozenilek
Copy link
Author

@compileLog shortcoming: this code

const num = {
 var val : i32 = 99;
 @compileLog("comp time val = {}", val);
 val = val + 1;
 val
};

prints

| "comp time val = {}", 99
Instead of expected printf-like formatted result.

@PavelVozenilek
Copy link
Author

Another problem with @compileLog:

This code:

const io = @import("std").io;

const num = {
 var val : i32 = 99;
 @compileLog("comp time val = {}", val);
 val = val + 1;
 val
};

pub fn main() -> %void {
  %%io.stdout.printf("In main runtime.\n");
}

does not invoke @compileLog at all. I sort of understand it - the num is not used and gets eliminated, together with its @compileLog. Only when I print the num value the @compileLog kicks in.

I think this is not what one expects. If some code contains active @compileLog it should be considered as "being used".

@PavelVozenilek
Copy link
Author

Third problem with @compileLog: I have 3 such calls. The compiler prints the expected output and then emits 3 the same errors. Each error takes 3 lines. All together 12 lines.

Example:

O:\zig0.1.1>zig build-exe b.zig
| "comp time inside the main"
| "comp time val1 = {}", 99
| "comp time val2 = {}", 99
O:\zig0.1.1\b.zig:14:5: error: found compile log statement
    @compileLog("comp time inside the main");
    ^
O:\zig0.1.1\b.zig:6:2: error: found compile log statement
 @compileLog("comp time val1 = {}", val1);
 ^
O:\zig0.1.1\b.zig:22:2: error: found compile log statement
 @compileLog("comp time val2 = {}", val2);
 ^

O:\zig0.1.1>

With highlighting it is looks worse.

Why not something as:

| "comp time inside the main"     ( b.zig:14:5 )
| "comp time val1 = {}", 99          ( b.zig:6:2 )
| "comp time val2 = {}", 99        ( b.zig:22:2 )

@PavelVozenilek
Copy link
Author

Inspired by "delete variable" thread I tried this:

const io = @import("std").io;

pub fn main() -> %void {

 var x : i32 = 1;
 x = undefined;
  %%io.stdout.printf("x = {}\n", x);
}

To my surprise it compiles, and prints out some garbage value.

Isn't this error, assignment of undefined at random place?

@PavelVozenilek
Copy link
Author

Following fails to compile:

pub fn main() -> %void {
  var x = 1 << 1;
}

with error:

O:\zig0.1.1\b.zig:6:3: error: variable of type '(integer literal)' must be const or comptime
  var x = 1 << 1;
  ^

@PavelVozenilek
Copy link
Author

Learning about @"foo" syntax. This compiles:

fn @"foo"() -> i32 { return 1; }

pub fn main() -> %void {

  %%io.stdout.printf("foo = {}\n", foo());
}

const io = @import("std").io;

It mixes @"foo" and foo and this seems wrong. I see no value in this, only potential confusion

@PavelVozenilek
Copy link
Author

It seems that I can export C incompatible name using @"foo" syntax:

This compiles:

export fn @"fo o"() -> i32 { return 1; }

@PavelVozenilek
Copy link
Author

I downloaded latest build ( 0.1.1.54a0db0d ) and copied the current Hello Word from docs:

const io = @import("std").io;

pub fn main() -> %void {
    // If this program is run without stdout attached, exit with an error.
    var stdout_file = %return io.getStdOut();
    const stdout = &stdout_file.out_stream;
    // If this program encounters pipe failure when printing to stdout, exit
    // with an error.
    %return stdout.print("Hello, world!\n");
}

I get this:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:6:32: error: no member named 'out_stream' in struct 'File'
    const stdout = &stdout_file.out_stream;
                               ^

O:\zig0.1.1>

As an aside: Hello World is supposed to be the most simple example, something very gentle to newcomers.

@PavelVozenilek
Copy link
Author

Crash in generated executable, version 0.1.1:

pub fn main() -> %void {
  comptime {
      @panic("comptime panic called");
  }
}

compiles OK. When result executable is invoked it prints

O:\zig0.1.1>b
comptime panic called
(stack trace unavailable for COFF object format)

and then crashes with standard Windows error dialog.

@PavelVozenilek
Copy link
Author

Similarly it crashes when I invoke @panic in runtime.

pub fn main() -> %void {
  @panic("panic in runtime");
}

compiles and results in

O:\zig0.1.1>b
panic in runtime
(stack trace unavailable for COFF object format)

and the crash dialog.

@PavelVozenilek
Copy link
Author

When I combine both compile time and run time @panic it doesn't compile:

pub fn main() -> %void {
comptime {
    @panic("comptime panic called");
}

  @panic("panic in runtime");
}

gives unexpected compiler error:

O:\zig0.1.1>zig build-exe b.zig
O:\zig0.1.1\b.zig:12:10: error: unreachable code
  @panic("panic in runtime");
         ^

O:\zig0.1.1>

I feel something is wrong here.

@PavelVozenilek
Copy link
Author

So called "child type" of pointers does not work, neither in 0.1.1 nor in the head.

This line in docs:

assert((&u32).child == u32);
gives:

O:\zig-head>zig build-exe b.zig
O:\zig-head\b.zig:6:16: error: type '&u32' has no member called 'child'
  assert((&u32).child == u32);
               ^

I am also scratching my head what this feature means and where it could be used.

@andrewrk
Copy link
Member

I welcome your feedback on Zig. In the future, I suggest this flow chart:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

3 participants