3 ms·
This program is not same to the Rust version. A more faithful version, assuming glibc, would look like this: #include <stdio.h> #include <stdlib.h>
by lifthrasiir 3y ago
This program is not same to the Rust version. A more faithful version, assuming glibc, would look like this:
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <errno.h>
void print_backtrace(void) {
void *traces[50];
char **symbols;
int num_traces, i;
num_traces = backtrace(traces, sizeof(traces) / sizeof(*traces));
strings = backtrace_symbols(traces, num_traces);
if (!strings) return;
for (i = 0; i < num_traces; ++i) {
fprintf("%d: %s\n", i + 1, strings[i]);
}
free(strings);
}
int main(void) {
static const char FMT[] = "Hello, World!\n";
static int EXPECTED = (int) (sizeof(FMT) - 1);
int ret = printf(FMT);
if (ret < 0) {
fprintf(stderr, "printf failed: %s\n", strerror(errno));
print_backtrace();
return 1;
}
if (ret != EXPECTED) {
fprintf(stderr, "printf failed: only %d characters were written\n", ret);
print_backtrace();
return 1;
}
return 0;
}
While this is still substantially different (for example, Rust's I/O buffering is different from C), this should be enough to demonstrate that this comparison is very unfair.
- rfoo 3y agoBuilding your code (I fixed a few typos, strings -> symbols, fprintf(" -> fprintf(stderr, ") with gcc -s -Os -fuse-ld=lld a.c && ls -al a.out leads to a 5496 bytes ELF though. Which is not much larger than just printf("Hello World!\n"), see sibling comment. I think the point is C "cheated" by including a lot of goodness (format, backtrace etc) in the shared library so they does not have to be copied to each binary.
- lifthrasiir 3y agoThank you for the actual testing (and sorry for typos...). Yes, a C version is small because it dynamically links to libc.so in this case, and I meant to compare against a statically linked version. I primarily wrote this example as a response to the claim that an equivalent---it isn't---C code with musl is very small.
- pca006132 3y agoThe problem is musl does not support execinfo. For a simple hello world, I managed to statically link with musl to get something with 7888 bytes.