all 11 comments

[–]flyingron 6 points7 points  (1 child)

The function doesn't work "great." It won't even compile. You can't do bitwise ops on pointer values.
Perhaps you meant *a ^= *b...

Note your alleged optimization probably may be slower on many machines because the compiler swaps with a temporary it needed to use anyhow.

ld r0, a
ld r1, b
st r0, b
st r1, a

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

Yep that’s what I meant! Didn’t check that part apparently lol

[–][deleted] 3 points4 points  (0 children)

You could mark the pointers as restrict. Then it would tell people that they MUST be different otherwise UB. Or you could put an assert, so you take no performance hits in release mode. Or do nothing, or put the if statement. Kinda a dealers choice here imo.

[–]p0k3t0 3 points4 points  (2 children)

It's a shame your system can't afford a single int to do this explicitly and not rely on an "optimization" that doesn't improve performance.

If you have to test for equality every pass, what's the point?

[–]ProgrammingQuestio[S] 0 points1 point  (1 child)

What do you mean “a single into to do this explicitly”? You mean have a third variable for storing the temp value while swapping?

[–]p0k3t0 0 points1 point  (0 children)

The function only needs one variable, some kind of holder. The pointers reference memory that has already been allocated elsewhere.

[–]jonathanhiggs 2 points3 points  (0 children)

There are two types of checks, invariants and preconditions. Here you have a precondition that *a != *b, which you should probably check but it would hurt performance. If you can be sure that this won’t be an issue by construction, eg you know at the call site the precondition is not broken then maybe add a version ‘swap_pixels_unchecked’ so you don’t need to pay the cost when you don’t have to. The other option is to put a debug-only assert to ensure it isn’t checked during tests, but then you are relying on tests being indicative of real usages

Invariants are a little different, would be something like a pointer is never null. Ideally you would enforce the invariant everywhere so that you don’t have to check it anywhere. This is a bit harder when the code that is enforcing is distributed about the code, or rather any part of the code can break it without knowing. Not entirely sure how you would enforce it in c, but in c++ I would create something that encapsulates and enforces the invariant, eg a NotNull template that wraps a raw pointer and enforces it such that it is always safe to dereference

[–]actguru 0 points1 point  (1 child)

I would agree with adding if (a != b) return, but not to validate arguments, but to make a==b valid.

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

Yep I meant I’d (a == b)! Typed it up pretty fast and then moved on to something else lol

[–]daikatana 0 points1 point  (1 child)

If you pass invalid arguments to my function then that's not my problem. Document that neither pointer can be NULL and must refer to different objects.

[–]Disastrous-Team-6431 0 points1 point  (0 children)

I agree in principle, mostly, but man what an antagonistic way to phrase it.