Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Returning an array in C++

Name: Anonymous 2009-10-26 20:39

PLEASE /prog/ help me out here. I've read and tested at least 5 "answers" to my question that I've found on google, but I can't get any of them to work. You guys are better than them though, right?

I wanted to call an array by reference in a function. Then, I learned that that was impossible. I tried returning the array, but you can't do that either.

Apparently, I need to do some shit with pointers to return the array. How the fuck do I do this?

Name: Anonymous 2009-10-27 22:59

>>51
int* f()
{
    int i = 6;
    return &i;
}
void g()
{
     int destroy_the_stack[1000];
}
int main()
{
    int* a = f();
    g();
    cout << *a << endl; //uh-oh spagetti-o's
    return 0;
}

Name: Anonymous 2009-10-27 23:23

>>53
No one does this anyways. >>51-sensei's way is good enough, and is actually the fastest come run-time.  I would prefer speed over taking care of some random boundary case like >>53-chan's anyday.

Name: Anonymous 2009-10-27 23:29

>>54
0/10. I award you no points, and may God have mercy on your soul.

Name: Anonymous 2009-10-27 23:30

>>54
Setting yourself up for failure. I hope you don't program flight control computers

Name: Anonymous 2009-10-27 23:38

>>56
Haha, I am glad I don't.  I write games in C++.  I am currently writing 3 games, and I am hoping to release them in 2010 (probably for Christmas.  One my have to wait until 2011) Unlike you, I can actually program, make money, and have fun at the same time, and in games every bit of optimization is important.

Name: Anonymous 2009-10-27 23:41

>>57
HOLY SHIT IT'S MAT DICKIE

Name: Anonymous 2009-10-27 23:43

>>58
Don't be silly, Mat Dickie isn't real

Name: Anonymous 2009-10-27 23:47

>>59
o ok

Name: Anonymous 2009-10-28 0:29

>>57
Wow, you're pretty awesome Anonymous.

>>53
Interestingly your destroy_the_stack array doesn't actually destroy the stack. You just declared some stack space which is never actually used. Try destroy_the_stack[0]=0;.

>>50
Way to not get the point. These are not features, they are anti-features. They are a massive overcomplication of something that should be extremely simple.

This thread is like the twilight zone. Since when does /prog/ like sepples?

Name: Anonymous 2009-10-28 0:33

>>61
you're right, however on my gcc it was sufficient to corrupt the 6 located at a, so I went with it. your mileage may vary based on your compiler

Name: Anonymous 2009-10-28 0:36

Here's a more to-the-point demo prog based on >>61's suggestion (and one which is definitely *not* a boundary case)
int* f()
{
    int i = 6;
    return &i;
}
void g()
{
     int destroy_the_stack = 9;
}
int main()
{
    int* a = f();
    g();
    cout << *a << endl; //uh-oh spaghetti-o's -- displays 9
    return 0;
}

Name: Anonymous 2009-10-28 0:40

>>61
Trolled by an incompetent troll

Name: Anonymous 2009-10-28 0:41

>>54
Oh holy fuck, I didn't actually fully interpret the depth of this post the first time around. You think that having a pointer to a stack variable and then calling a function that overwrites it is a 'random boundary case'?

Honestly. You are seriously fucking retarded. You know when you build -Wall -pedantic and the compiler gives you hundreds of warnings? Those aren't a joke. You are seriously fucking up. In my last two jobs, I introduced the policy of building everything -Wall, and it all has to come out no warnings to ship.

Also what the fuck makes you think >>51 is fastest at run-time? It doesn't fucking do anything except give you a pointer to a literal, applied dangerously somewhere on the stack. None of these examples even make any sense. It certainly hasn't allocated an array; it has fuck all even to do with arrays.

And 'allocating an array' is an extremely generic concept; you can't just point at some code and say which is fastest. How big does the array need to be? Is it thread-local? Small? Function scoped? Then you can probably alloca() it. Is it small but shared? Consistent size? You can maybe pool it. Threaded? Add locks to the pool. Is it fairly large? malloc(). Quite large? mmap().

Honestly though all of this is superfluous. malloc() is going to be your best bet in almost all situations, since a good malloc() does all the above for you except stack allocations (which often cause more problems than they solve). You can never figure out the best way to do these things besides profiling, and honestly you always have bigger bottlenecks (like the fact that you have allocations outside of loading in the first place). The allocator is all powerful; trust the allocator.

Please tell me what your games are so I can avoid their bugs and security vulnerabilities.

Name: Anonymous 2009-10-28 0:44

>>65
A new is fine too

Name: Anonymous 2009-10-28 0:48

>>66
Not for arrays.

Name: Anonymous 2009-10-28 0:50

>>67
Do go on

Name: Anonymous 2009-10-28 1:03

>>68
Well, it's garbage for anything other than pointers or primitive types simply because of constructors. If you're trying to set up some kind of pool (say a pool of particle objects), to use new[] you have to subvert the usual constructor/destructor scheme and provide your own init/destroy functions. This is dumb. You're much better off malloc()'ing the memory, and using in-place construction/destruction, so you can have proper constructors and destructors for your objects without the associated allocation costs.

As far as primitive types go, there are safer ways. These sorts of arrays are usually either fixed compile-time sizes, so you're better off having them as a field of a struct/class, or for growable arrays, so you're better off using some sort of vector class (or std::vector if you're lazy). And no, there is no overhead to an std::vector of primitives aside from the size of the array (which, if you're sizing dynamically, you generally need to have stored anyway).

Name: Anonymous 2009-10-28 1:21

>>69
To add to this, boost has a memory pool built in that does exactly this, because getting this all correct and exception-safe in sepples can actually get quite complicated (easy to fuck up). As usual, something that should be simple is instead excruciating, but because it has a shitty prefab template for you to use people will cheer about how powerful their language and library is. Go sepples!

Name: Anonymous 2009-10-28 1:35

>>50
Love to!

int* make_array(void* (*alloc)(size_t)) {
  return (int*) (*alloc)(sizeof(int) * 5);
}


Check that shit out! Custom allocator and everything. Pretty bitching, right? It doesn't have the smart pointers, but guess what, you don't need them in C because there's no such thing as exceptions (nor threads. Remember kids, threads are evil. Isolate processes; avoid shared memory; communicate through pipes; the UNIX way). Memory management in C is pretty damn easy.

Name: Anonymous 2009-10-28 2:01

>>71
I think I had the UNIX equivalent of an orgasm

Name: Anonymous 2009-10-28 2:11

>>72

phiber@scout:~$ cum > filthy.sock

Name: Anonymous 2009-10-28 2:12

>>72
[Anonymous@/prog/ ~]$ yes oh yes

Name: Anonymous 2009-10-28 2:15

>>61
Since when does /prog/ like sepples?
Much as I hate Sepples, I hate people who Sepple wrong even more.

Name: Anonymous 2009-10-28 5:43

>>73
Lol I do that sometimes if I can't find a tissue. Else underwear

Name: Anonymous 2009-10-28 6:07

>>73
Why is sock an attribute of filthy, instead of the other way around
Sock.filthy = True

Name: Anonymous 2009-10-28 6:13

>>77
no no no your doing it wrong. The Sock object should implement the Filthy interface if it's filthy

Name: Anonymous 2009-10-28 6:24

>>78
Enjoy your Robust Scalable Turnkey Solutions

Name: Anonymous 2009-10-28 6:58

>>78
You can't dynamically implement an interface depending on whether the sock is filthy or not though. Your move.

Name: Anonymous 2009-10-28 7:57

>>80
Yes you can. NOW YOUR'E THINKING WITH RUBY

Name: Anonymous 2009-10-28 8:07

>>71
but guess what, you don't need them in C because there's no such thing as exceptions

Right. You have returns instead. I mean, goto cleanup;.

You never programmed anything remotely complex in C, I guarantee that.

Name: Anonymous 2009-10-28 8:13

>>82
what was your point?

Name: Anonymous 2009-10-28 9:15

>>82

in C there's no way to protect against unwinding the stack, moron

Name: Anonymous 2009-10-28 9:19

>>82
nope. the closest thing to exception handling C has is signals.
it's the manly way of doing things.

Name: Anonymous 2009-10-28 9:28

>>85
setjmp & longjmp

Name: Anonymous 2009-10-28 10:39

>>86
TEN POINTS FOR GRYFFFFIINNNNDORRRRRRRR

Name: Anonymous 2009-10-28 10:53

You can implement exception handling unportably in C, as long as you can write some assembly code for your platform.

Name: Anonymous 2009-10-28 10:59

>>83-85 I feel I'm being [spoiled]trolled[/spoiled].

>>71 said that I, personally, don't need smart pointers in C because "there's no such thing as exceptions". Being a professional C programmer, I was deeply offended by such a moronic statement.

Exception mechanism is merely a tool that provides one particular way for solving a certain class of problems. Not having this exact tool only means that I have to implement the solution in a slightly different way. I open a file, try to read something from it unsuccessfully and then need to close it before reporting error myself, with exceptions I put close in the finally block, without exceptions I make a "finally" label near the end of the function, close the file there, and set up return value and goto there whenever something fails.

The problem I'm solving is the same, the structure of the solution is roughly the same, and only the thin layer of syntax and semantics of an actual language produces somewhat different implementation.

I'm greatly saddened by the stupidity and arrogance of >>71,83-85, who not only can't see beneath that superficial layer, but are entirely convinced that there is nothing at all beyond that.

Of course I'd need more than one logical exit point in a function if it can fail somewhere. Of course I'd have to map these onto the real exit point(s) somehow and clean up all resources, and why the fuck anyone would think that 'throw' is somehow different from 'return' in this respect? Of course I would appreciate RAII greatly while I'm at it.

Name: Anonymous 2009-10-28 11:39

>>89
Stopped reading at you claiming to be offended by a moronic statement. You should by now know (if you lurked long enough, that is) that every post here contains at least 75% moronic content.

Name: Anonymous 2009-10-28 13:00

>>90
(if you lurked long enough, that is)
Non-moronic content.

Name: Anonymous 2009-10-28 13:03

>>89
RAII
Stopped reading there.  Did you mean RAF?

Name: Anonymous 2009-10-28 13:06

>>90
Of course I was not deeply or at all offended, you moron. It's a polite figure of speech that substitutes for "I'd rip your filthy tongue out and made you swallow it if I were unfortunate to listen to your bullshit in person". The kind of thing you do to people who are trying to offend you (unsuccessfully, of course).

Name: Anonymous 2009-10-28 13:36

lol RAII hacks.

I'll take my WITH- macros and UNWIND-PROTECT instead.

Name: Anonymous 2009-10-28 18:07

>>82
>>89

Not having this exact tool only means that I have to implement the solution in a slightly different way. I open a file, try to read something from it unsuccessfully and then need to close it before reporting error myself, with exceptions I put close in the finally block, without exceptions I make a "finally" label near the end of the function, close the file there, and set up return value and goto there whenever something fails.
...So you're saying compiler exception support is superfluous and unnecessary? Are you trying to prove my point here? What was your point again?

Of course I'd need more than one logical exit point in a function if it can fail somewhere. Of course I'd have to map these onto the real exit point(s) somehow and clean up all resources, and why the fuck anyone would think that 'throw' is somehow different from 'return' in this respect?
Nice job shithead. You don't seem to understand that the point of exceptions is that they propagate through many functions on the stack. Smart pointers and RAII aren't syntactic sugar for goto cleanup; they are syntactic sugar for longjmp and a thread-local cleanup stack (and in many compilers that's exactly how they're implemented).

This is why smart pointers aren't needed in C. Unless you're using a library that actually longjmps (like libpng), there's no danger that some exception will propagate through your function; unless the thread aborts your 'goto cleanup' will always be called, so it's sufficient to cleanup resources.

(And this is entirely unrelated to the issue of reference counting, which is often conflated with smart pointers; lots of C libraries use reference counting).

You never programmed anything remotely complex in C, I guarantee that.

Hilarious, from one professional C programmer to another. Ask the Linux kernel devs what they think about exceptions and smart pointers.

Name: ​​​​​​​​​​ 2010-10-24 18:12

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List