Live data from Hacker News

Cleaning up X server warnings

keithp.com

21–30 of 34 posts

Re: Cleaning up X server warnings

#21
post #15

Earlier quoted context omitted.

That's the theory, sure. But in practice, if you know all your targets support the right "#pragma pack" and "__attribute__((packed))" and other markers that you use - what's wrong with making use of them?

The fact that you can't know all of your future targets will support that is a problem. Endian issues are also a big problem here. The need to byte-swap everything eliminates a lot of the convenience. It's also way too easy to make breaking changes to the struct, since there's no standard way to mark a struct as being something that you serialize/deserialize, and normally you can change struct fields at will in C cod…

> The fact that you can't know all of your future targets will support that is a problem.

To be honest I've even seen compilation issues coming up between ubuntu 10.x and 11.x. I don't worry about future targets that much. Until they're tested, I assume they will not work.

Re: Cleaning up X server warnings

#22
post #6

Interesting. Interesting how the -Wcast-qual warnings are unfixable , so it shouldn't exist. Damned if you do, damned if you don't. A lot of warnings seem to fall on this. Or warnings that would make sense on stricter languages but doesn't make sense on C exactly because of what you can do with C , like, for example, reading serialized data, then casting it to (MyStructure *) And a little bit offtopic, but GTk have s…

I thought that the issue is the const-ness of the variables, and nothing to do with casting void* ->sometype* Essentially, they are making use of const pointers to ensure that the code doesn't change the data. (gcc would throw a warning if you did). BUT: the problem comes when you want to free() the data. A strict interpretation of C would be that you can't free() something that's const, because it clearly is alterin…

The BSD solution to this problem is __DECONST(), a macro which basically casts through `uintptr_t`.

    #define __DECONST(type, var)   ((type)(uintptr_t)(const void*)(var))

Re: Cleaning up X server warnings

#23

It always surprised me that GCC has no source-level way of controlling compiler warnings. Many programmers (and gcc apparently) live with the assumption that compiler warnings must always be fixed. This is largely false. Compiler warnings are there to help with additional information, not to be something to fix. There are many cases where the compiler issues a warning which must be ignored. Many compilers support pra…

Sure, sometimes they warn about totally valid behaviors. The "all warnings must be fixed" dogma arises not out of the belief that all warnings are errors, but rather that the value of having compiler warnings catch bugs early is well worth the cost of changing code style to conform to the compiler's warnings suite.

Re: Cleaning up X server warnings

#24
post #15

Earlier quoted context omitted.

The fact that you can't know all of your future targets will support that is a problem. Endian issues are also a big problem here. The need to byte-swap everything eliminates a lot of the convenience. It's also way too easy to make breaking changes to the struct, since there's no standard way to mark a struct as being something that you serialize/deserialize, and normally you can change struct fields at will in C cod…

"The fact that you can't know all of your future targets will support that is a problem." I don't see this as much of a problem as endianness, but yeah, maybe, x86 made us accustomed. And you can use portable types, defined on headers (linux does that, like u8, u16, etc) But sometimes you know your target won't change (for a long time) "It's also way too easy to make breaking changes to the struct, since there's no s…

Does it really make your program slower? That padding you have to eliminate for this technique is added for speed, after all. The initial read may be faster, but every access to the data is going to be slower.

I'm not quite sure what the BMP file format is supposed to be an example of, especially since file formats are separate from techniques used to read or write them.

Re: Cleaning up X server warnings

#25

Interesting. Interesting how the -Wcast-qual warnings are unfixable , so it shouldn't exist. Damned if you do, damned if you don't. A lot of warnings seem to fall on this. Or warnings that would make sense on stricter languages but doesn't make sense on C exactly because of what you can do with C , like, for example, reading serialized data, then casting it to (MyStructure *) And a little bit offtopic, but GTk have s…

If you're not careful and not on x86-likes, then reading serialized data like that unaligned values might cause errors.

Re: Cleaning up X server warnings

#26

Earlier quoted context omitted.

That's the theory, sure. But in practice, if you know all your targets support the right "#pragma pack" and "__attribute__((packed))" and other markers that you use - what's wrong with making use of them?

Also, if you're passing data between two processes (e.g. your code fork()d a child), you can be sure that the data format is going to match, no packing required. (still need to ensure alignment in memory though)

This is not necessarily true. Lots of systems support running 32-bit and 64-bit binaries simultaneously, and structs won't necessarily be portable between the two. Some versions of Mac OS X even supported running 32-bit PowerPC binaries (in an emulator, but supported directly by the OS) next to both 32-bit and 64-bit x86 binaries, so you could not only get size mismatches, but also endian mismatches.

This does not apply to simply forking, of course, but it does apply to the "two processes" case in general.

Re: Cleaning up X server warnings

#27
post #15

Earlier quoted context omitted.

That's the theory, sure. But in practice, if you know all your targets support the right "#pragma pack" and "__attribute__((packed))" and other markers that you use - what's wrong with making use of them?

The fact that you can't know all of your future targets will support that is a problem. Endian issues are also a big problem here. The need to byte-swap everything eliminates a lot of the convenience. It's also way too easy to make breaking changes to the struct, since there's no standard way to mark a struct as being something that you serialize/deserialize, and normally you can change struct fields at will in C cod…

Some years ago I had a discussion with a then-colleague who pointed out something interesting that stuck with me: the world has mostly settled on little endian. If you stay outside of certain niches you are unlikely to ever see a big endian CPU.

Time was you might have to run on a SPARC or PowerPC or whatever. But x86 and little-endian ARM have pretty much won for most people.

I don't think my friend was right that this means you can totally ignore the issues, but I have to admit he was right that from a strictly practical perspective it's not the huge deal it was in the 90s. I agree with you that you don't know how the future will break you, but my guess is the momentum of binary compatibility will keep it so for a while.

Re: Cleaning up X server warnings

#28
post #15

Earlier quoted context omitted.

The fact that you can't know all of your future targets will support that is a problem. Endian issues are also a big problem here. The need to byte-swap everything eliminates a lot of the convenience. It's also way too easy to make breaking changes to the struct, since there's no standard way to mark a struct as being something that you serialize/deserialize, and normally you can change struct fields at will in C cod…

Some years ago I had a discussion with a then-colleague who pointed out something interesting that stuck with me: the world has mostly settled on little endian. If you stay outside of certain niches you are unlikely to ever see a big endian CPU. Time was you might have to run on a SPARC or PowerPC or whatever. But x86 and little-endian ARM have pretty much won for most people. I don't think my friend was right that t…

That's a good point, and he's largely right. On the other hand, I've been burned before (Macs were always going to be 68k until they went PPC, they were always going to be PPC until they went Intel, they were always going to be Intel until Apple made these tiny mini-Macs that were ARM) and I'm wary of making assumptions anymore.

Re: Cleaning up X server warnings

#29
post #28

Earlier quoted context omitted.

Some years ago I had a discussion with a then-colleague who pointed out something interesting that stuck with me: the world has mostly settled on little endian. If you stay outside of certain niches you are unlikely to ever see a big endian CPU. Time was you might have to run on a SPARC or PowerPC or whatever. But x86 and little-endian ARM have pretty much won for most people. I don't think my friend was right that t…

That's a good point, and he's largely right. On the other hand, I've been burned before (Macs were always going to be 68k until they went PPC, they were always going to be PPC until they went Intel, they were always going to be Intel until Apple made these tiny mini-Macs that were ARM) and I'm wary of making assumptions anymore.

This is usually my kind of instinct too, which is why I was attributing the other viewpoint to someone else. But it was interesting to understand where someone like that is coming from. You can spend a lot of time adding the right swaps etc. but in the end if you don't own hardware that works that way, aren't testing it regularly, from a certain perspective you may be wasting your time.

OTOH I recall that insightful article from Rob Pike about how the "right" way to do it in a testable fashion is to not think in terms of swapping at all, and just do shifts that are portable regardless of architecture. http://commandcenter.blogspot.com/2012/04/byte-order-fallacy...

(By the way, in your 68k -> PPC -> Intel -> ARM example, the endianness only changes once. This was actually part of my friend's original argument, that endianness changes are even more costly than the instruction set, and platform vendors would be unwise to change it. "Modern" CPUs support both endianness types, so those shipping ARM platforms are in effect consciously deciding to be the same as Intel.)

Re: Cleaning up X server warnings

#30
post #26

Earlier quoted context omitted.

Also, if you're passing data between two processes (e.g. your code fork()d a child), you can be sure that the data format is going to match, no packing required. (still need to ensure alignment in memory though)

This is not necessarily true. Lots of systems support running 32-bit and 64-bit binaries simultaneously, and structs won't necessarily be portable between the two. Some versions of Mac OS X even supported running 32-bit PowerPC binaries (in an emulator, but supported directly by the OS) next to both 32-bit and 64-bit x86 binaries, so you could not only get size mismatches, but also endian mismatches. This does not ap…

On the same machine, it's going to be rare

But the most common occurrence of this I can think are online games.

Post reply on HN