the inky void – Telegram
the inky void
37 subscribers
20 photos
3 videos
24 links
deranged mamblings of a madman
Download Telegram
Some time ago I came across a riddle. What do you think will the following code do?
#include <bits/stdc++.h>
using namespace std;

int ost[] = {0, 1, 2, 3, 4, 5, 6};

int main()
{
for(int i = 0, val = ost[0]; i < 7; val = ost[++i]){
cout << val << endl;
}

return 0;
}
a) print numbers from 0 to 7
b) print numbers from 0 to 7
c) print numbers from 0 to 7
d) print random stuff and the segfault

a|b|c are indeed correct, if you don't compile it with optimizations, but if you do it will indeed crash. The reason why is pretty interesting and took me a while to figure out: basically the last call to operator<< in cout << val << endl is inlined and has a potential throw in its small code, val = ost[++i] is undefined behavior for i = 6 and should not be reached, meaning for the compiler the loop always breaks before the last element is reached, it assumes that the exit is the aforementioned raise and optimizes the loop condition out, as well as putting the throw after the loop and replacing the call with a break.

This behaviour can be reproduced in both c and c++ by replacing cout << val << endl with any function call that will be inlined and can throw exit from the program and any usage of ost (so that the array access is not optimized out), however it is a lot less likely in c (the highest chance for it to show up is near user redefined memory allocations which exit if malloc fails), For a synthetic example
#include <bits/stdc++.h>
using namespace std;

int ost[] = {0, 1, 2, 3, 4, 5, 6};

void mb_exit(int n) {
if (rand() == 1337 + n) {
exit(1337);
}
}

int main()
{
for(int i = 0, val = ost[0]; i < 7; val = ost[++i]){
mb_exit(val);
}

return 0;
}
lol gcc allows (clang doesn't as "this is a complex feature which is infrequently used, so it is unlikely to be implemented anytime soon") to allocate closures on the stack, automatically disabling nx and making the stack executable. Very cool idea that fits into c semantics perfectly. Unfortunately it's too late to build security technologies around it so I doubt it will ever see much use, let alone replace int (*f) (void *, ...), void *arg. All it does is absolutely (ie not via call, but via a constant and register) call the underling function with the pointer to a part of the stack with the closure variables in a register not used by the calling convention.
1 typedef int (*func)(int);
2
3 void make_closure(int n) {
4 int closure(int m) { return n + m; }
5 func f = &closure;
→ 6 }
7
8 int main() {
9 make_closure(1337);
10 }
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "a.out", stopped 0x5555555551b1 in make_closure (), reason: SINGLE STEP
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x5555555551b1 → make_closure(n=0x539)
[#1] 0x5555555551d6 → main()
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ x/3i f
0x7fffffffe0d4: movabs r11,0x555555555139
0x7fffffffe0de: movabs r10,0x7fffffffe0d0
0x7fffffffe0e8: rex.WB jmp r11
gef➤ x/10i 0x555555555139
0x555555555139 <closure>: push rbp
0x55555555513a <closure+1>: mov rbp,rsp
0x55555555513d <closure+4>: mov DWORD PTR [rbp-0x4],edi
0x555555555140 <closure+7>: mov rax,r10
0x555555555143 <closure+10>: mov QWORD PTR [rbp-0x10],r10
0x555555555147 <closure+14>: mov edx,DWORD PTR [rax]
0x555555555149 <closure+16>: mov eax,DWORD PTR [rbp-0x4]
0x55555555514c <closure+19>: add eax,edx
0x55555555514e <closure+21>: pop rbp
0x55555555514f <closure+22>: ret
the time has come again for me to create a channel. I have recovered most of the old posts, but this time it will be a little bit different. i will try to consistently provide some meaningful content, but with more leeway for short snippets of information, thoughts and mostly music.
the inky void pinned «the time has come again for me to create a channel. I have recovered most of the old posts, but this time it will be a little bit different. i will try to consistently provide some meaningful content, but with more leeway for short snippets of information…»
пон
thanks for the suggestion
haven't seen that in a looooong time
👍2
а из моего окна площадь красная не видна...
🤔5😢4
> men enjoy the goth girl aesthetic because it represents a woman that is externally consistent with her inner state. that is to say - evil
🔥2
настроение вспомнить детство