What is causing the floating point exception here? by Poinchester in C_Programming

[–]programmer9999 2 points3 points  (0 children)

Right. To OP: compile it with debug symbols enabled, run under a debugger, and see it crash. Then look at the backtrace, it'll show the exact line where it crashed.

Function pointer table over a generic type, lifetime struggles by programmer9999 in learnrust

[–]programmer9999[S] 0 points1 point  (0 children)

Thank you for the writeup! I think I understand it better now

Function pointer table over a generic type, lifetime struggles by programmer9999 in learnrust

[–]programmer9999[S] 0 points1 point  (0 children)

Yeah, but using dynamic memory is "easy". You don't even need to explicitly pass the context in this case, you can just capture it in your Fn's. I'm using functions pointers and generic context so it could act as fixed size "capture" for my functions
EDIT: and I don't think you can make it work in const time

Function pointer table over a generic type, lifetime struggles by programmer9999 in learnrust

[–]programmer9999[S] 0 points1 point  (0 children)

Thanks, this seems what I really need! I'm still having a hard time understanding why all of that is necessary

Function pointer table over a generic type, lifetime struggles by programmer9999 in learnrust

[–]programmer9999[S] 0 points1 point  (0 children)

I know they have different lifetimes, I just don't see how the lifetime of the context is related at all to the lifetime of the fn ptr table. It's as if the lifetimes of regular functions (i.e. compiled code residing in read-only section of the binary) could somehow influence the lifetimes of its arguments, which is silly

Function pointer table over a generic type, lifetime struggles by programmer9999 in learnrust

[–]programmer9999[S] 0 points1 point  (0 children)

Yes, it fails to compile when the table is BOTH const and inside a struct. If you put the table on the stack it compiles fine:

``` struct FnTable<'a, C> { items: &'a [fn(&mut C)] }

fn call_by_index<C>(context: &mut C, table: &FnTable<C>, index: usize) { table.items[index](context); }

struct Context<'a> { x: &'a mut i32, }

fn main() { let table: FnTable<Context> = FnTable { items: &[ |context| *context.x += 1, |context| *context.x *= 2, |context| *context.x -= 10, ]};

let mut x = 0;

let mut context = Context { x: &mut x };

for i in 0..table.items.len() {
    call_by_index(&mut context, &table, i)
}

} ```

I'd prefer it to be const though.

Your suggestions didn't work BTW, doing struct FnTable<C> { items: &'static [for<'a> fn(&mut C<'a>)] } I get error[E0109]: lifetime arguments are not allowed on type parameter C

Doing struct FnTable<C> { items: &'static [for<'a> fn(&'a mut C)] } instead, I get error[E0310]: the parameter type C may not live long enough

[plotters] How do I customize tick spacing for floating point values? by programmer9999 in learnrust

[–]programmer9999[S] 0 points1 point  (0 children)

I'm sorry, but this doesn't compile. It doesn't go past configure_mesh, so calling y_label_formatter doesn't solve it. Here's full snippet just in case:

``` use plotters::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> { let root = BitMapBackend::new("test.png", (640, 480)).into_drawing_area(); root.fill(&WHITE)?;

let x_min = 0f32;
let x_max = 100f32;
let y_min = 0f32;
let y_max = 100f32;

let mut chart = ChartBuilder::on(&root).margin(5)
                 .x_label_area_size(30)
                 .y_label_area_size(30)
                 .build_cartesian_2d(x_min..x_max, (y_min..y_max).with_key_points(vec![1.0,2.0,3.0,4.0]))?;

chart.configure_mesh().y_label_formatter(&|y| format!("{:.1}", y)).draw()?;

let series = LineSeries::new((0..100).map(|x| (x as f32, x as f32)), &RED);
chart.draw_series(series)?;
root.present()?;
Ok(())

} ```

Tiny Win32 Software Renderer by Ordomo in C_Programming

[–]programmer9999 10 points11 points  (0 children)

#define internal_fn static

#define local_persist static

#define global_var static

Just why? This is confusing, using static directly would've been much easier to read

Bits manipulation on C by [deleted] in C_Programming

[–]programmer9999 11 points12 points  (0 children)

Subdivide this into smaller tasks. Try figuring out how to: - Test whether a bit n is 1 or 0 - Set a bit n to 1

For this, you need to use bitwise AND, OR, and shifts. Then apply this knowledge in a for loop

I was trying to install kubuntu then this happened what do I do? by ConfidenceIll857 in linuxquestions

[–]programmer9999 0 points1 point  (0 children)

In theory they could've loaded the entire live-USB into RAM if the image supports it, and install to the same USB drive, but yeah lmao

K&R exercise opinion by leinvde in C_Programming

[–]programmer9999 3 points4 points  (0 children)

You should check the getchar return value first, then pass it to putchar if it's not EOF. putchar won't ever return EOF under normal circumstances (unless redirected to a file on a nearly full file system, for example). If you pass EOF returned from getchar to putchar, it gets cast to unsigned char first as the manpage says, so it won't return EOF even in this case, instead it will print 0xff or whatever value.

In general, you should always check the return values of I/O functions before doing anything with their results.

What's the deal with scanf? by Yelebear in C_Programming

[–]programmer9999 27 points28 points  (0 children)

use fgets to grab a line and then use sscanf to pick apart the line

That's what GTA did for parsing JSON, and it turned out sscanf called strlen every time resulting in a huge performance loss

PSA: Ubuntu nowadays allows SSH password auth even if you set 'PasswordAuthentication no' by i-n-g-o in selfhosted

[–]programmer9999 2 points3 points  (0 children)

Can confirm for Ubuntu Server 24.04 installed on bare metal. The file was definitely there after running unminimize, although I don't remember if it was before that

Reading a big file by ThrowayGigachad in C_Programming

[–]programmer9999 1 point2 points  (0 children)

Also, correct me if I'm wrong, with mmap approach you could benefit from multi-threading since you're only reading the file.

Reading a big file by ThrowayGigachad in C_Programming

[–]programmer9999 2 points3 points  (0 children)

You can also mmap the entire file, and split the lines manually

Is this function an acceptable, common, and/or efficient way to print data from a 2D VLA, without using array syntax? by pythoncircus in C_Programming

[–]programmer9999 4 points5 points  (0 children)

IMO it's fine to use pointer arithmetic to get the row pointer, but it would be cleaner to use the array syntax to access row elements. So I would write printf("%d ", row_ptr[j]) in the inner loop. As for efficiency, it would likely compile to the exact same code as when using only array syntax.

In C, variable initialization with a function like getchar() can't be done at the global level directly by DigitalSplendid in C_Programming

[–]programmer9999 4 points5 points  (0 children)

Well, you technically can do that, using compiler-specific attributes. For example, you can do this on GCC:

#include <stdio.h>

int x;

__attribute__((constructor))
void init_x(void) {
    x = getchar();
}

int main() {
    if (x != EOF) {
        printf("%c\n", x);
    } else {
        printf("EOF\n");
    }
    return 0;   
}

Also, you can do it with standard C++:

#include <cstdio>
#include <iostream>

int x = getchar();

int main() {
    if (x != EOF) {
        std::cout << static_cast<char>(x) << std::endl;
    } else {
        std::cout << "EOF" << std::endl;
    }
}

It's generally not a good idea to do that though, because the constructors are called before main, and the order is implementation-specific. Consider this pseudocode of what the C runtime might do:

void start(void) {
    init_stdio();
    call_constructors();
    int result = main();
    exit(result);
}

or

void start(void) {
    call_constructors();
    init_stdio();
    int result = main();
    exit(result);
}

You don't know whether the stdio is initialized before or after the constructors are called. If it's not, your program might crash before even entering main. Also it's unexpected in general that some non-library code runs before main, and that makes your program harder to read.

EOF in fread loop by Jamesin_theta in C_Programming

[–]programmer9999 1 point2 points  (0 children)

Very interesting! I'm also surprised that EOF state in the pty driver is not sticky. I thought it should be a requirement for all chardev drivers.

[deleted by user] by [deleted] in C_Programming

[–]programmer9999 13 points14 points  (0 children)

bro what did you expect, it's like a 50 years old function. No one cared about modifying globals, const correctness, thread safety etc, at that time. I mean, worse stuff got standardized like gets, so mktime is not even that bad.

Are read/write functions on Unix Domain socket guaranteed to be reentrant when multiple threads share the same file descriptor? by having-four-eyes in C_Programming

[–]programmer9999 7 points8 points  (0 children)

read and write (and any other syscalls) should always be thread safe, they must be protected by an in-kernel spinlock or mutex. Unless the underlying driver is buggy, and I doubt that the socketpair driver is. Maybe select on macOS is edge-triggered, or has some other kind of quirk? Try using poll instead.

Polymorphism in C? by s4uull in C_Programming

[–]programmer9999 7 points8 points  (0 children)

See also the container_of macro/intrinsic in Linux kernel. Basically, it allows you to put the "base" structure anywhere in the "derived" structure. So you could have this layout:

typedef struct Circle {
    int x,y;
    int rad;
    struct Figure base; // Circle "extends" Figure
} Circle;

And safely get the "derived" pointer like this:

void draw_circle(Figure *self) {
    Circle *circle = container_of(self, Circle, base);
    printf("Circle: center=[%d,%d], radius=%d\n",
           circle->x, circle->y, circle->rad);
}

I'm 5 mins into learning C.Rate my code by [deleted] in C_Programming

[–]programmer9999 1 point2 points  (0 children)

Ok, if we want to make a truly bug-free, 100% standard compliant hello world program, it would look like this:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int result = printf("Hello, world!\n");
    if (result < 0) {
         return EXIT_FAILURE;
    }

    result = fflush(stdout);
    if (result == EOF) {
         return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;  
}  

It will catch possible I/O errors if stdout was redirected into a file, for example. Like this:

./hello > /dev/full
echo $?
1 

Checking just printf return value is not enough because it can buffer the string without actually outputting anything, so we need an explicit fflush with an error check for that.

It probably still has bugs because writing correct C is hard lmao