Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> If you chose Rust instead, you're going to have a bad time.

Naw.

    /* main.c */
    #include <stdio.h>
    #include <stdint.h>
    uint8_t answer();
    int main(int argc, char** argv) {
        printf("%d\n", answer());
        return 0;
    }

    // example.rs
    #[no_mangle] extern "C" fn answer() -> u8 {
        println!("The answer is:");
        42
    }

    # test.sh
    rustc --crate-type staticlib -o example.a example.rs
    gcc main.c example.a -lpthread -ldl
    ./a.out

    $ ./test.sh
    The answer is:
    42
Workflows using `cargo` instead of `rustc` are also sane and easy.


    #[no_mangle] extern "C"
All due respect to Rust, which is a fantastic language, what this line says is "here is a C function written in Rust".

You can of course do the same thing with C++ and with D, allowing all three to check the box for interoperability. And with Rust you get everything Rust offers: so you can write in the `extern "C"` dialect while getting memory-safety guarantees within the library, that's not nothing.

What Zig offers is the ability to write ordinary Zig and call that from C. That's part of what it's designed to do.

This is interoperability by design, rather than by configuration. It's simply a different thing, and considered along this singular dimension, I would assert that it's better.

I didn't, and wouldn't, say that Zig has the potential to replace Rust. I said that about C, and explained why.


> What Zig offers is the ability to write ordinary Zig and call that from C.

You say that, but Zig appears to suffer from the exact same problem you point out in my Rust code:

    export
https://ziglang.org/documentation/master/#Exporting-a-C-Libr...

Perhaps I'm mistaken. How do I directly call Zig's `std.debug.print` from C? Or Timestamp.unixEpoch as defined here? https://ziglang.org/documentation/0.7.1/#Doc-comments

There's a bunch of rust crates containing macros, binaries, and build scripts that cut down on Rust's boilerplate as well. While there are some rough edges and room for further improvement, I am far happier with Rust's C interop than I am with the C interop of most other languages. Zig might have a touch more polish, but the bit I originally quoted made Rust sound like it was a good order of magnitude worse than Zig at C interop, which I just can't agree with.

One of the very first things I did when learning Rust was write a test library and drop it into an existing C++ codebase. I've also experimented heavily with cross compiling it to pretty much anything I can get my hands on. It was a good time, not a bad one.


I found it very difficult to deal with C macros, though. That said, I have no idea how zig deals with that problem either.


Zig can handle C macros, you can see this if you use the zig translate-c option on the CLI which will convert any C code to Zig. This does make it the most usable C ffi I have used, as it means it really works with even difficult C code.


This seems like unsolvable problem - if you'd want to allow calling C macros from your new language, you would have to be C superset. So no memory/thread/... safety, weird syntax inherited from C, ...


This was one of the most redeeming things about Objective-C. It is a superset of C, and when I was working with it, I found myself writing the high-level stuff in ObjC, but with a lot of pure-C functions sprinkled in. It was really nice for working with C libraries like OpenGL, because you could find an example online and directly apply it without going through any kind of translation step. It was a really cool feature to have.


I share a similar experience with C++.

However that compatibility is also what makes Objective-C and C++ impossible to ever be fully safe, without breaking compatibility with the C subset.

Static analysis help, but only when all code is available.


It isn’t so black and white.

Nim, if you let it use C as a backend, will let you use C macros, despite being generally safe and not remotely a C superset.

Yes, the use of C macros (and any kind of ffi) is unsafe, that cannot be avoided. But it doesn’t need to be a c superset (and indeed, when you use JS as a backend, or the native LLVM backend, you get no access to C macros)


It's probably impossible in general, but you could probably deal with a bunch of common cases fairly easily (like constants)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: