this post was submitted on 15 Jan 2025
104 points (93.3% liked)

Programming

17823 readers
455 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities [email protected]



founded 2 years ago
MODERATORS
 

I’m working through the vulkan tutorial and came across GLFW_TRUE and GLFW_FALSE. I presume there’s a good reason but in looking at the docs it’s just defining 1 and 0, so I’m sorta at a loss as to why some libraries do this (especially in cpp?).

Tangentially related is having things like vk_result which is a struct that stores an enum full of integer codes.

Wouldn’t it be easier to replace these variables with raw int codes or in the case of GLFW just 1 and 0?

Coming mostly from C, and having my caps lock bound to escape for vim, the amount of all caps variables is arduous for my admittedly short fingers.

Anyway hopefully one of you knows why libraries do this thanks!

all 50 comments
sorted by: hot top controversial new old
[–] [email protected] 5 points 20 hours ago

i just like namespacing my variables anyway so there's no chance of any conflicts and so you can easily change something one place instead of everywhere

[–] [email protected] 20 points 1 day ago

GLFW is a C library, not a C++ one, and an old one at that, and so the reason is that a long time ago, there was no bool in C. Every library would make their own true and false bc it's handy to have.

Nowadays, the type _Bool has been added to C, and C++ has built-in bool, but you can still see the legacy of no boolean in C as to use the type name "bool" as well as the key words "true" and "false" for 1 and 0, you have to include "stdbool.h," as well as in custom types in these old GL-adjacent libraries.

[–] [email protected] 37 points 1 day ago (1 children)

I work with young people starting out in IT, so I'm used to getting screenshots, and I'm so used to screenshots made with a phone instead of just capturing the screen, that I've stopped complaining... But come on! At least evaluate the result of the first picture and maybe do another if it's illegible.

[–] [email protected] 3 points 1 day ago

Yeah that’s fair— this is my focus workstation so don’t have any messaging apps or email to send the screenshot but def could have taken a second picture.

[–] [email protected] 123 points 1 day ago (3 children)

This is often done for backward compatibility, as stdbool.h which provides true and false wasn't standard before C99 and even though that's more than 25 years ago now a lot of old habits die hard.

[–] SpaceNoodle 60 points 1 day ago (1 children)

Also, plenty of embedded systems don't use the C standard library.

[–] [email protected] 1 points 23 minutes ago

stdbool.h (along with float.h, limits.h, stdarg.h, stddef.h, stdint.h, and some other library facilities) is required to be provided even in freestanding environment so, at least as long as you use an ISO C conformant compiler, you can always include those even if you don’t have a libc implementation

[–] [email protected] 22 points 1 day ago (1 children)

Yeah in the late 90's I was coding in C++ and I'm pretty sure I had to define true and false manually.

[–] SpaceNoodle 6 points 1 day ago

I seem to recall using the true and false literals C++ in the late '90s ... looks like they were in the C++98 standard, but it's not clear which pre-standard compilers might have supported them.

[–] [email protected] 13 points 1 day ago

Ahh this makes some sense

[–] [email protected] 39 points 1 day ago (2 children)

My brain is so used to seeing political content that I read "why do liberals define their own true and false" and was already like "what kind of shit take am I going to have fun reading today"

[–] topherclay 4 points 20 hours ago (1 children)

That should probably be red alert wakeup call for you right?

[–] [email protected] 2 points 12 hours ago
[–] [email protected] 9 points 1 day ago (1 children)

I can give you a shit take if you want one, but I don’t have shiitake mushrooms.

[–] [email protected] 2 points 1 day ago

I like my shit takes wrapped in beef rolls, in case you come across some more :)

[–] [email protected] 84 points 1 day ago* (last edited 1 day ago) (8 children)

My boss insisted, before I arrived at the company, that everything in the database be coded so that 1 = Yes and 2 = No, because that's the way he likes to think of it. It causes us daily pain.

[–] [email protected] 9 points 1 day ago

I'm reminded of an old job's database where every key was named "id_foo" instead of "foo_id"

You didn't have user_id. You had id_user. You didn't have project_id, you had id_project. Most of the time, anyway. It was weird and no one could remember why it was like that. (Also changes to the DB were kind of just yolo, there wasn't like a list of migrations or anything)

[–] [email protected] 18 points 1 day ago

If that is something your boss is managing, get the fuck out of there.

[–] lurklurk 5 points 1 day ago

Get a better boss

[–] forrcaho 27 points 1 day ago* (last edited 1 day ago) (2 children)

Something like if (stupid_bool & 0x01) should work for those.

[–] [email protected] 16 points 1 day ago

Yeah of course we convert, but it effectively means you need this little custom conversion layer between every application and its database. It's a pain.

[–] [email protected] 12 points 1 day ago* (last edited 1 day ago) (1 children)

I imagine this would still lead to a never ending stream of subtle logic errors.

from bossland import billysbool, billysand
from geography import latlong
import telephony

def send_missile_alert(missiles_incoming: billysbool, is_drill: billysbool, target: latlong):
  if billysand(missiles_incoming, not is_drill):
    for phone in telephony.get_all_residents(target):
      phone.send_alert("Missiles are inbound to your location")

Can you spot the bug?

[–] [email protected] 9 points 1 day ago (1 children)

The conventional 'not' would not behave differently for the two non-zero values. Insidious.

[–] [email protected] 12 points 1 day ago (1 children)

Correct! I made a number of other mistakes (edited away now due to shame), but that's the one I made on purpose.

[–] [email protected] 2 points 1 day ago

I mean, if you have a billysbool class anyway, you'd make its truthiness correct according to bossman's scheme, and then the not operator would work correctly.

[–] [email protected] 12 points 1 day ago (1 children)

Does your boss frequently browse the database table records outside the API?

[–] [email protected] 4 points 1 day ago

Oh you have no idea. There is no teaching this guy.

[–] affiliate 4 points 1 day ago (2 children)

why not just take it a step further and make true = “Yes” and false = “No”

[–] [email protected] 2 points 1 day ago* (last edited 1 day ago)

I have seen this, but with "Y", "N" instead. That was the way the database stored it and the way the UI displayed it, but everything inbetween converted to boolean instead, because there was logic depending on those choices. It wasn't that bad, all things considered, just a weird quirk in the system. I think there was another system that did just use those strings plain (like WHERE foo = 'Y' in stored procedures), but nothing I had to work with. We just mapped "Y" to true when reading the query results and were done with it.

(And before anyone asks, yes, we considered any other value false. If anyone complained that their "Yes", "y" or empty was seen as false, we told them they used it wrong. They always accepted that, though they didn't necessarily learn from it.)

[–] [email protected] 2 points 1 day ago

It would probably carry less risk, but in terms of bytes used this would be even worse. And we have other problems there that I'd tell you about but it would make me too sad.

[–] [email protected] 1 points 1 day ago* (last edited 1 day ago) (1 children)

Microsoft SQL Server has a bit type and you always use 0 and 1 and cast/convert them. No native bool type. It's a hassle.

[–] [email protected] 3 points 1 day ago (1 children)

Well that would be ok, because any standard tool for interfacing with the database would transparently treat bit in the DB as bool in the code. I think many DBs call it a bit rather than a bool.

[–] [email protected] 2 points 1 day ago (1 children)

that assumes you don't write any SQL

[–] [email protected] 2 points 1 day ago

I'm used to ORM layers where you can write SQL queries but you're basically converting the results to objects before you use them. These kinds of things tend to handle bits OK, and bit parameters can usually be set as booleans directly. I haven't used SQL Server in a while though so maybe it isn't as convenient as that.

[–] [email protected] 16 points 1 day ago

I love the description as well. "One." "Zero."

[–] [email protected] 31 points 1 day ago (3 children)

It's because the Booleans sometimes are flipped in display-server technology from the 1980s, particularly anything with X11 lineage, and C didn't have Boolean values back then. More generally, sometimes it's useful to have truthhood be encoded low or 0, as in common Forths or many lower-level electrical-engineering protocols. The practice died off as popular languages started to have native Boolean values; today, about three quarters of new developers learn Python or ECMAScript as their first language, and FFI bindings are designed to paper over such low-level details. You'll also sometimes see newer C/C++ libraries depending on newer standards which add native Booleans.

As a fellow vim user with small hands, here are some tricks. The verb gU will uppercase letters but not underscores or hyphens, so sentences like gUiw can be used to uppercase an entire constant. The immediate action ~ which switches cases can be turned into a verb by :set tildeop, after which it can be used in a similar way to gU. If constants are all namespaced with a prefix followed by something unique like an underscore, then the prefix can be left out of new sections of code and added back in with a macro or a :%s replacement.

[–] [email protected] 1 points 18 hours ago

Seriously helpful thanks! One of my friends working on a G15 restoration project pointed out this notation to be after you did— yet while they use 0 for truth they used 20 for false so not sure were they got the second idea. And your vim tip saved me a bunch of hand ache!

[–] [email protected] 3 points 1 day ago

By the way, you can use g~ to get the effects of tildeop without needing to set it.

[–] [email protected] 14 points 1 day ago

In VisualBasic "true" would be represented as -1 when converted to an int because it's all 1's in twos complement.

[–] [email protected] 7 points 1 day ago

I found the comments/answers about backwards compatibility of not defined booleans and negative true interesting and plausible.

What I first thought of was that TRUE and FALSE can be redefined, so it serves as ensurance that within the library consistent values are being used no matter what other libs and callers do with their typing and definitions.

[–] over_clox 16 points 1 day ago* (last edited 1 day ago) (2 children)

Some languages define True as -1, which is NOT False...

[–] [email protected] 10 points 1 day ago (1 children)

which is NOT False…

You really didn't need this; I would have just assumed that you were speaking the truth.

[–] over_clox 9 points 1 day ago (1 children)

CONST False = 0, True = NOT False

NOT as in the binary operator. What's NOT of 0 in a 32 bit space? 0xFFFFFFFF, which is -1, which is ≠ 1

Different languages, and even different programmers might interpret the concept and definition of True and False differently, so to save any ambiguity and uncertainty, defining your own critical constants in your own library helps make sure your code is robust.

[–] [email protected] 2 points 1 day ago (1 children)

So... all that is NOT False either, I presume?

[–] SwordInStone 1 points 1 day ago (1 children)

they mean every bit is different

[–] [email protected] 0 points 1 day ago

I don't know; their comment seemed pretty much the same throughout...

[–] pHr34kY 2 points 1 day ago

I once wrote a library to replace an older one. Someone did this, and users were multiplying variables by booleans and negating them in formulas.

I just made the new library less stupid and left the users to clean up their mess when migrating.

[–] qx128 14 points 1 day ago* (last edited 1 day ago)

It’s for the extra helpful documentation. You see, in this fantastic example, after the author set GLFW_TRUE to 1, he explained the deep and profound meaning of the value. This exemplifies that the number 1 can also be written as a word: “One”! Some people might be able to figure this out, but the author clearly went above and beyond to make the code accessible to the open source community, encouraging contributions from anyone who’s considering improving the code. Furthermore, this follows the long held tradition of man pages - explaining the nuance of the code, in preparation for telling others to RTFM when they arrogantly ask a question.

[–] slazer2au -2 points 1 day ago

Because JavaScript exists