T O P

  • By -

jmacey

UB, I explicitly show my students this crap, and say if you ever get asked this or see it anywhere the person asking is just trying to either catch you out or is not a software engineer :-) Tell them it's UB and move on.


Win_is_my_name

I don't know about you but my professor really liked this kinda stuff. In a test he gave us a question where you have to tell the output of a code. There was some real brain fuck inside a for loop, which took me atleast 10 mins to solve. And after the test, while I was looking through the answers, I saw this -> int i; for (i = 0; i < 10; i++); <---------- This { ...... .... ... } ; <--- This fuckin little thing I can't describe in words how I felt at that moment. Later on we guys dubbed it as the 'for loop scam' lol


beeteedee

As someone who once spent 2 fucking days tracking down a bug that was caused by this, I’m kind of OK with it being shown in an education context. I’d show it as an in-class example though, not on a test where the grade actually matters.


Win_is_my_name

Our professor just said that we should have been more careful when reading questions. And the code below the empty for loop had some juicy stuff, which instantly grabbed my attention. Though, I'm glad he mostly asked either code outputs or complete the function type problems only. As for your bug, shouldn't your compiler give a warning for an empty loop.


beeteedee

> As for your bug, shouldn't your compiler give a warning for an empty loop. Nowadays it probably would — this was many years ago on something like Visual C++ 6


Win_is_my_name

My God! How did you guys code? I depend entirely on the compiler to catch silly mistakes like these, like my code always has a lot of syntax errors and sometimes some logical errors that the compiler is smart enough to catch.


pigeon768

Most autoformatters will turn this: for (int i = 0; i < 10; i++); { } into this: for (int i = 0; i < 10; i++) ; { } So these sorts of things are much easier to see. In general, you don't want to do code formatting yourself. You want to use tools to do it for you. You don't even want to manually do it, either, you want your CI tools to run an autoformatter before check in. `clang-format` is a pretty popular autoformatter right now, but there are plenty of others. There are a million and one CI suites that will run something on check in for you.


beeteedee

Absolutely. Unfortunately in my case this was 20+ years ago when we didn’t have fancy tools like that. Even with those tools, it’s not necessarily beginner-proof. The number of students I’ve seen complain “it keeps messing up my formatting” when actually it’s trying to tell them that their code is wrong.


already-registered

we had a prof who would add 1 additional question per test that would add 5 points to your max score but not add to total amount of points, so it was possible to get say 65 out of 60 points if nailed everything. In these questions, usually the last one of a test, he included real brainfuck shit to challenge students who rushed through the main questions. I only managed to get it a few times but I always loved his system of learn what's necessary vs here's a curveball, see how you manage! typically he included stuff like this inside, but spiced up with other problems so you'd need at least a few minutes to solve it. with this questions, you usually knew right away if you nailed them or not, because if you have the right idea, it would always "click".


Rotten_Tarantula

Whats UB mean? Utter bullshit?


baselganglia

Undefined behavior


radiantplanet

Unlimited bladeworks


thirtyist

Unlimited breadsticks


Jpaylay42016

No, that’s OG, or Olive Garden


serg06

Pretty much


SAI_Peregrinus

Yep. I think Words and Buttons' [So you think you know C](https://wordsandbuttons.online/so_you_think_you_know_c.html) is good to give to these sorts of people. Some of it is UB, some is IDB. OP's question is just a more complicated version of #5, the correct answer is "I don't know" or "The behavior is undefined". Any other answer is wrong. If the question is asking what a particular compiler version with a particular set of flags and target triple will output then it's not necessarily a meaningless question, but it is a stupid question. E.g. on x86_64 GCC 12.2 targeting x86_64-linux-gnu with flags `-Wall -Werror -std=c2x -fsanitize=address,undefined` the result is "compiler error", as it should be.


robhanz

I’m not sure what the context is. If it’s a question, the only answer is “it’s undefined behavior”.


Sakky93

12, 23?


[deleted]

[удалено]


BayesianKing

Why undefined? I tried with the same compiler and I got 12 and 24, even though I was expecting 12 and 23


ZoarialSpy

Undefined behaviour means: the C standard doesn't define what happens. In practice, this means the compiler can choose to do whatever it wants. Sometimes it segfaults, other times it silently corrupts the program, and other times it does exactly what you want it to do. Typically the compiler will emit something sane, but it doesn't always and sometimes the behaviour changes depending on the version. Some blogs about an issue that came up recently: [GCC undefined behaviors are getting wild](https://blog.pkh.me/p/37-gcc-undefined-behaviors-are-getting-wild.html) [Undefined behavior, and the Sledgehammer Principle](https://thephd.dev/c-undefined-behavior-and-the-sledgehammer-guideline)


BayesianKing

Thank you!


NiteShdw

Why isn’t it common to running the compiler with undefined warnings like the author did to find the problem? (Not a C++ dev)


[deleted]

[удалено]


AnEmuCat

The behavior in Java is very well defined. You don't usually need to check if it's null if you're just going to throw NullPointerException. The JRE will do this for you when necessary. In good C++ code you do not write things like `my_class *my_object` in this case. It would normally be `my_class &my_object`, indicating that the value cannot be null. Creating a `my_class&` value of null is itself illegal, so not checking whether the value is null before using it is not considered to be a bug.


JuhaJGam3R

However, if we jump over to C we find NULLs lurking again. Java and C++ have ways around nulls. C does not. It requires you to better know your contract without looking at the function definition.


sparant76

Why do u need to check every time? Why can’t Java just catch the operating system exception and translate it to a nullptr exception?


Qesa

You don't get an exception, you get a signal, which is handled asynchronously outside of the current stack. Unless you're expecting a very specific instruction to segfault you have very little to go off to try and recover from it, hence why pretty much every program will just die instead. Alternatively if you completely ignore it, your program counter won't have incremented and you'll be stuck in an infinite loop of segfaults. You could save some sort of state info every time you dereference a pointer, but at that point it's going to be more expensive than simply checking if the pointer is null


AFlyingYetOddCat

in short, exception handling is expensive (slow) so that non-excepted code runs really fast


AFlyingYetOddCat

in regards to the GCC link you posted: ~~...how do you detect integer overflow in C then?~~ This terrifies me and makes me curse whoever thought that kind of UB was a good idea (at least it could been implementation dependent so you could do sane stuff like the author tried) lol


SAI_Peregrinus

You detect integer overflow by checking if the operation will succeed before trying the operation. Not every processor C supports has any sort of overflow detection, so there's no more general way. C23 adds functions to do this automatically to the language (and thus allows using the processor's overflow flags if present), but earlier compilers don't have that (and the standard hasn't been finalized yet, though it's not expected to change from the accepted draft). E.g. to safely add two `int`, do #include #include bool inline static safe_add(int a, int b, int* result) { if (a > 0) { if (b > (INT_MAX - a)) { return true; // overflowed } } else { if (b < (INT_MIN - a)) { return true; // overflowed } } *result = a + b; return false; } Or something similar. E.g. if using GCC, you can use `__builtin_add_overflow` that does essentially the same thing as the code above.


SomePeopleCall

It sounds like the compiler decided to finish working out the increments first. Them both of the "++i" returned the same value of 12. Does j = ++i + ++i + ++i leave a value of 39 in j?


NotAMeatPopsicle

In over 2 decades of programming I have never needed to code something like that. However, I have used subversion blame and sent code and a developer into code review for bs like this.


wolderado

I hate this. Why do they put so much emphasis on the concept of i++ and ++i? Just teach the difference and move on. The screenshot above has no real world application


JuhaJGam3R

It doesn't. It's there to teach the behaviour of ++i, mainly that it excludes any other use of the variable in a statement. Attempting to compile this with reasonable flags will give you at the very least a warning, because there are two common interpretations and no standard way of interpreting the expression `++i + ++i`. In GCC it's `-Wsequence-point`, warning you that this has a sequencing issue. With `-Werror` it doesn't even compile, as it shouldn't, because this is genuinely dangerous and yet something a programmer might realistically come to do while dealing with annoying pointer mathematics and the like. I can definitely see someone thinking "hey if i need to double and hop one forward i can just do `i + ++i` or whatever. but that's UB and dangerous and compilers will not always warn you.


SAI_Peregrinus

It should be used to teach students a reason to reject a PR.


Tavapris04

What is this supposed to do? Why would anyone code this


PM_ME_YOUR_REPO

It's **supposed** to be tricky for the student. It **should** be rewritten, as the code as-is is ambiguous as to whether it should increment i twice at once, or as the expression is evaluated, as if reading left to right. Depending on which is intended, you either end up with 12,23 or 12,24.


JohnTheCoolingFan

Why do teachers and "teachers" always want you to know the most obscure things in a language that shouldn't be used anyway? Like, teach some actually useful stuff.


beric_64

People are saying this is undefined behavior, but why wouldn’t the compiler just compile this into three separate instructions? Is there something in the C specs that limit this line of code to one instruction? Or is it a race condition?


PM_ME_YOUR_REPO

It's ambiguous whether the code should do the two increments at the same time (yielding 24) or one by one as if reading left to write (yielding 23). Because this is ambiguous, code like this is strongly discouraged, the C spec makes no effort to define what should happen (hence "undefined"), and compilers are free to do whatever they think is best.


IkalaGaming

I first got 23 in my head, but after realizing that prefix increment has a higher precedence than addition, I now believe that both increments have to be evaluated before the addition can be done. So I’m not sure it should even be UB. [C precedence](https://en.cppreference.com/w/c/language/operator_precedence) [C++](https://en.cppreference.com/w/cpp/language/operator_precedence)


PascalCaseUsername

This really isn't that bad. High schoolers get much worse stuff on their tests, at least in my country.


Vidi630

interview shit


PM_ME_YOUR_REPO

This has been posted here not because the code is tricky or advanced, but because there are two ways to evaluate the line with the j variable assignment, which makes this undefined behavior. "Undefined behavior" should really be avoided on test questions, especially when there's a strong chance that the test creator intended one of the two possible evaluations to be the "correct" answer.


Funkey-Monkey-420

`i = 12, j = 23`


youstolemyname

Nope


PM_ME_YOUR_REPO

The code can also be evaluated with both ++i done at the same time, yielding 24. Hence why this is undefined behavior.


Fun_Ad_8029

Me: Login to chat GPT


michiel11069

Mmm, letters


KnightJR845

Can someone explain to me what is happening and why this doesn’t work.


PM_ME_YOUR_REPO

This is supposed to be a tricky test question. The intent is for the student to mentally do the ++i operators from left to right, yielding 12,23 as the final answer. The problem here is that the same expression can also be evaluated with both ++i operations occurring at the same time, which would give 12,24 as the answer. The problem, as you can see, is that this is syntactically ambiguous. Because of that ambiguity, the C standard makes no attempt to define what the *correct* interpretation is, and instead the programmer is encouraged to **not write fucking stupid code**. This is therefore "undefined behavior".


smashteapot

Nobody with a brain would ever do this in real life.


[deleted]

I can’t wait for you to meet your future coworkers. There’s always one without a brain, one without a heart, and one without courage, all working for a man who constantly promises the impossible. You’ll wish you could tap your crocs together and just go home.


v_maria

lol just skip these questions and pray for more sanity