Betsy writes:
I found this snippet recently in a 20-year-old RPG program.
Ah, yes, twenty years ago, RPG, that means this was written in the 1970s. What? No. That can't be right? That's how long ago?
Joking about my mortality aside, in the early oughts, most of the work around RPG was in keeping old mainframe systems from falling over. That entirely new code was being written, that new projects were being started twenty years ago is not a surprise, but it's unusual enough to be remarkable. That said, the last release of RPG was in 2020, so it clearly keeps on keeping on.
In any case, this developer, we'll call them "Stephen", needed to create an array containing the numbers 12 through 16.
Let's take a peek at the code.
D RowFld S 3 0 DIM(5)
D X S 3 0
D Y S 3 0
C EVAL X = 12
C FOR Y = 1 TO %Elem(RowFld)
C EVAL RowFld(y) = X
C EVAL X = X + 1
C ENDFOR
The first three lines create some variables: RowFld, which is an array containing 5 elements, and will hold our offsets. X and Y are going to hold our numeric values.
We set X equal to 12, then we start a for loop from 1 to the length of our RowFld. We set the element at that index equal to X, then increment X.
The code is awkward, but is not exactly the WTF here. This particular program displays a file and a subfile, and these values are used to position the cursor inside that subfile. The array is never iterated over, the array is never modified, the array would 100% be better managed as a set of constants, if you didn't want to have magic numbers littering your code. More than that, the location of the subfile on the screen has never changed. And let's be fair, this didn't get rid of magic numbers, it just made them one through five, instead of 12 through 16, as the indexes in the array are just as arbitrary.
In other words, there's no point to this. Even if the specific version of RPG didn't have constants variables that you handle like constants would be fine (my checks on the documentation seem to imply that CONST first appeared in version RPG IV 7.2, which makes it look like circa 2016).
But there's one more bit of weirdness here. Stephen had several years of experience with RPG, and all of that experience was from the "free-format" era of RPG. You see, way back in 2001, RPG finally freed itself from its dependency on punchcards, and started allowing you to write code as just strings of text, without requiring certain things to exist in certain columns. This was a generally positive enhancement, and Betsy's team immediately adopted it, as did everyone running the latest versions of RPG. All new development was done using the "free-format" style, so they could write code like normal people. They even had a conversion tool which would do some simple string manipulation to convert legacy RPG programs into the modern style, and had basically abandoned the legacy style without looking back.
Except for Stephen, who insisted on the column oriented format. Who protested when anyone tried to modify their code to modernize it at all. "Oh, we used free-format at my last job," Stephen said when pressed, "but it's confusing and columns are just cleaner and more readable."
Eventually, someone else wrote a program that absorbed all the functionality in Stephen's program. Stephen kept plugging away at it for a few years afterwards, because a handful of users also refused to migrate to the new tool. But eventually they left the company for one reason or another, and Stephen found himself without users for his work, and left with them.
C++11 gave us enum class and while it’s great to have scoped enums I don’t find it great for error handling. Let’s talk about why.
C++ Enum Class and Error Codes
by Mathieu Ropert
From the article:
Most of my readers, I hope, have been able to use C++11 for a while now (if not hello, I’m sorry the world has changed to become this weird during your 14 years sleep). With it came a small change that allowed for better scoping of names without resorting to weird quirks:
enum class. The idea is simple: owing to C,enumvalues in C++ belong to the class or namespace they are declared in but if we add theclasskeyword to the declaration they know become their own scope instead of leaking to their parent.This was a simple quality of life change in the compiler to address a weakness in the language that folks usually worked around by either adding long prefix to the enum values (C style) or wrapping them within structs or classes (C++98/03 style). And with it came the incentive to migrate C era error code enums to scoped enums. But there’s a catch.
Scared Stanley stammered "I'm afraid of how to explain to the tax authority that I received $NaN."
Our anonymous friend Anon E. Mous wrote "I went to look up some employee benefits stuff up and ... This isn't a good sign."
Regular Michael R. is not actually operating under an alias, but this (allegedly scamming?) site doesn't know.
Graham F. gloated "I'm glad my child 's school have followed our naming convention for their form groups as well!"
Adam R. is taking his anonymous children on a roadtrip to look for America. "I'm planning a trip to St. Louis. While trying to buy tickets for the Gateway Arch, I noticed that their ticketing website apparently doesn't know how to define adults or children (or any of the other categories of tickets, for that matter)."
It feels like ages ago, when document databases like Mongo were all the rage. That isn't to say that they haven't stuck around and don't deliver value, but gone is the faddish "RDBMSes are dead, bro." The "advantage" they offer is that they turn data management problems into serialization problems.
And that's where today's anonymous submission takes us. Our submitter has a long list of bugs around managing lists of usernames. These bugs largely exist because the contract developer who wrote the code didn't write anything, and instead "vibe coded too close to the sun", according to our submitter.
Here's the offending C# code:
[JsonPropertyName("invitedTraders")]
[BsonElement("invitedTraders")]
[BsonIgnoreIfNull]
public InvitedTradersV2? InvitedTraders { get; set; }
[JsonPropertyName("invitedTradersV2")]
[BsonElement("invitedTradersV2")]
[BsonIgnoreIfNull]
public List<string>? InvitedTradersV2 { get; set; }
Let's start with the type InvitedTradersV2. This type contains a list of strings which represent usernames. The field InvitedTradersV2 is a list of strings which represent usernames. Half of our submitter's bugs exist simply because these two lists get out of sync- they should contain the same data, but without someone enforcing that correctly, problems accrue.
This is made more frustrating by the MongoDB attribute, BsonIgnoreIfNull, which simply means that the serialized object won't contain the key if the value is null. But that means the consuming application doesn't know which key it should check.
For the final bonus fun, note the use of JsonPropertyName. This comes from the built-in class library, which tells .NET how to serialize the object to JSON. The problem here is that this application doesn't use the built-in serializer, and instead uses Newtonsoft.JSON, a popular third-party library for solving the problem. While Newtonsoft does recognize some built-in attributes for serialization, JsonPropertyName is not among them. This means that property does nothing in this example, aside from add some confusion to the code base.
I suspect the developer responsible, if they even read this code, decided that the duplicated data was okay, because isn't that just a normal consequence of denormalization? And document databases are all about denormalization. It makes your queries faster, bro. Just one more shard, bro.
The Budapest C++ Meetup was a great reminder of how strong and curious our local community is. Each talk approached the language from a different angle — Jonathan Müller from the perspective of performance, mine from design and type safety, and Marcell Juhász from security — yet all shared the same core message: understand what C++ gives you and use it wisely.
Trip report: Budapest C++ - Breaking & Building C++
by Sandor Dargo
From the article:
More than a hundred people registered, and the room quickly filled up with local developers eager to hear three technical talks. The atmosphere was lively and welcoming — it showed the strength of the C++ community in Budapest. In 2027, even WG21 might come to Hungary!
The evening began with Jonathan Müller’s talk, Cache-Friendly C++, followed by my own session on Strongly Typed Containers. Finally, Marcell Juhász closed the event with an insightful and hands-on presentation on Hacking and Securing C++.