Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
more falafel please
Feb 26, 2005

forums poster

j4cbo posted:

I wrote this. You'll need a decent grasp of x86 assembly to comprehend the horror...

code:
/* void iret(int addr, ...); */
.global iret
iret:
        add $4, %esp 
        iret

x86 isn't my strong suit, but isn't that basically infinite recursion without overflowing the stack? I guess I'm assuming that 'iret' on its own is a call of some sort.

Adbot
ADBOT LOVES YOU

more falafel please
Feb 26, 2005

forums poster

nebby posted:

Yeah, I mean, I catch myself using "i" when I know better. The problem is, I see it as a bad habit when most see it as acceptable. When you are writing a loop, you can quickly get into trouble if you have nested loops and have i, j, or even k being used. Additionally, and more importantly, using "i" is ignoring an opportunity to introduce a good name into the code. You're looping over it for a reason, so you should usually opt to provide hints as to why you're doing so in the name. If you are looping over a list of apples that need to be put into another bucket, instead of "i", you could use "iAppleForBucket" and not worry about confusing it with another loop variable and potentially remove a comment saying "// We loop over the apples for the bucket" !

I don't need that comment:
code:
for (int i = 0; i < bucketOfApples.size(); ++i)
{
    bucketOfApples[i].bob();
}
Yes, there may be better ways of doing it, but I don't believe you honestly can't look at that loop and immediately know what it's doing. That comment would be entirely superfluous. If it said // Bob all the apples in the bucket, that'd be one thing, but calling the loop var appleToBob wouldn't change that.

more falafel please
Feb 26, 2005

forums poster

It's better than
code:
if(something){
  DoWork();
^^ TWO loving SPACES EVEN THOUGH THE REST OF THE PROJECT USES TABS
}else{
  DoOtherWork();
}

more falafel please
Feb 26, 2005

forums poster

Zombywuf posted:

Sheesh, M-x indent-region and get on with your life.

That's the problem -- I'm stuck doing that (well, gg=G, but same difference). This code is five years old, and full of crap like this -- defining log macros badly so they need double parentheses, bizarro mixes of Systems Hungarian, CamelCase, camelCase, and under_score_words, depending on this guy's mood that month, static members called m_ivpFoo (instance variable). And of course design problems -- the initializer list for one class's ctor is 124 lines long.

I've asked him if he's going to fix any of it, but he says it'd be too much effort when he could just rewrite it.

The problem of course is that there's never time -- it's always crunch.

more falafel please
Feb 26, 2005

forums poster

That Turkey Story posted:

No it doesn't. That code has undefined behavior. It is never safe to invoke a non-static member function through a null pointer.

It may be undefined behavior because the underlying implementation is unspecified, but what the compiler's going to generate is this (using C as portable assembly):
code:
struct foo;

bool foo_is_null(foo* this) {
    return this == 0;
}

int main() {
  foo *a = 0;
  printf("%d\n", foo_is_null(a));
}
I understand why "undefined behavior" generally means no-no, but in cases like this it doesn't matter what the standard says to some degree, because it works with the only way you would implement POD types.

more falafel please
Feb 26, 2005

forums poster

bt_escm posted:

The best/worst one I've seen is
php:
<?
if(false){


50+ lines of code that aren't used any more

}
?>
I guess the developer didn't need those lines of code anymore and didn't care or understand what php was going to do with them everytime the script loaded.

In the project I just finished, there's thousands of lines that are either #if 0'd out or #ifdef JOHNSMITH, where John Smith is a programmer who hasn't worked here in 2 years.

more falafel please
Feb 26, 2005

forums poster

We had a girl programmer in our group once for a while but she wrote this code
code:
char* p = malloc(somesize);

p = malloc(somesize);

more falafel please
Feb 26, 2005

forums poster

biznatchio posted:

The first person to post a picture of Leah Culver gets a boot up the rear end from yours truly.

http://commons.wikimedia.org/wiki/Image:Grace_Hopper.jpg

more falafel please
Feb 26, 2005

forums poster

Flobbster posted:

It should be
code:
for(size_t i = 0; i < str.length(); i++)
:colbert:

++i damnit!

more falafel please
Feb 26, 2005

forums poster

Standish posted:

I'd be surprised if it could optimize that for std::iterators, remember the STL is just another library as far as the compiler is concerned -- from the compiler's point of view, it doesn't know anything about iterator semantics and std::iterator::operator++() (the prefix overload) and std::iterator::operator++(int) (the postfix overload) are completely distinct functions which could have completely different sideeffects.

In contrast, int is a built-in type so the compiler does know exactly when it's safe to substitute ++int for int++.

Well, it depends on the iterator. I think every implementation of std::vector<T> just typedefs iterator to T* (except for vector<bool>, but that's a whole other story), because it needs to have exactly the semantics of a pointer to an element in the vector. So, in many cases, there is not operator++() or operator++(int) functions. The standard specifies only that the operations ++it and it++ are legitimate, not that they're implemented as functions.

And since (in most cases, anyway) iterators are associated with class templates like containers, the implementation is known at compile time, so the compiler would be able to inline std::list<T>::iterator::operator++/operator++(int) (as an example of an iterator type that does have to be implemented).

So the point is that the compiler is usually smarter than you. However, you should Say What You Mean, and since it++ has the semantics of returning the old value, you don't usually mean that.

more falafel please
Feb 26, 2005

forums poster

Gotos are a better way of cleaning up in error conditions than big nested ifs in situations where exceptions either are not available or cannot be used for reasons such as performance.

This is essentially Linus' argument.

more falafel please
Feb 26, 2005

forums poster

code:
Foo* FindFooFromFooID(FooID id)
{
    Foo* pFoo = 0;
    for (list<foo>::iterator it = fooList.begin(); it != fooList.end(); ++foo)
    {
        if ((*it).GetID() == id)
        {
            pFoo = &(*it);
            return pFoo;
        }
    }
    return 0;
}

Foo& GetFooFromFooID(FooID id)
{
    Foo* pFoo = 0;
    for (list<foo>::iterator it = fooList.begin(); it != fooList.end(); ++foo)
    {
        if ((*it).GetID() == id)
        {
            pFoo = &(*it);
        }
    }
    if (pFoo != 0)
    {
        return *pFoo;
    }
    else
    {
        assert(FALSE, "Trying to get a nonexistent Foo");
    }
}
Now aside from the copy-paste mentality of this code, it's not *too* bad. Use FindFooFromFooID when you might be looking up something that isn't there, use GetFooFromFooID when you know it should be there.

Every usage of either of these functions looks like this:
code:
Foo* pFoo = FindFooFromFooID(ID);
if (pFoo)
{
    Foo& Foo = GetFooFromFooID(ID);
    // do stuff
}
// ELSE COMPLETELY HIDE PROGRAMMING OR WORSE YET ART ERRORS
I got to get rid of this today. This was a win.

more falafel please
Feb 26, 2005

forums poster

Munkeymon posted:

On the subject, I got to extend a code base for a student project that did stuff like this:

code:
if(successCondition)
{
  //do some cleanup
  throw new WhateverIdoHappenedToWorkException(returnValue);
}
else
{
  /*do the same cleanup with a couple things possibly 
    commented out for some reasonbecause copy and paste 
    is like a control structure, right?*/
  throw new WhateverIdoFailedException();
}
And the calling code had a big try/catch/catch/catch... block to handle the 'result'. Some had multiple success or failure 'conditions' that had to be caught. This technique was used instead of events, or at least mostly in places events should have been used*, in C#. It was all written by a 4th year CS undergrad.

*Class functions would throw exceptions on completion (or error) to be caught by other class functions. There were also a few places where whoever wrote it clearly could have used a switch if it had occurred to him.

Exceptions are like goto, only they're just "gosomewhere".

more falafel please
Feb 26, 2005

forums poster

Evis posted:

Not if they're implementing bool in the same way it was done in C, but if you're using the builtin type is it still potentially a problem? I could see weirdness if there was an order of operations issue that the coder wasn't aware of. I suppose if you were doing some more explicit manipulation of memory you could run into something weird too. (I'm not really advocating using ==true, I'm really just interested in learning more about the issue)

What are you talking about

more falafel please
Feb 26, 2005

forums poster

zootm posted:

I've no idea, I'm afraid I don't use Windows so finding it is kinda impossible for me.

Edit: I lie, Google apparently knows about these things. See under Breaking on Exceptions on this page.

That is some crazy-rear end poo poo. Good stuff though, would be nice if that worked more often.

$10 completely fake dollars says it doesn't work with GCC and -O3.

As ehnus said, there's always int 3 (which can also be triggered with *(int*)13 = 3;

Coincidentally, *(int*)13 = 3 is a pretty good way of causing a breakpoint (not always a recoverable one) on any platform :)

more falafel please
Feb 26, 2005

forums poster

vanjalolz posted:

Lets bring this thread back to easy to understand coding horrors :)

A few days ago I saw return ((x > 0) ? true : false); and there were like 10 of these in a line.

I've seen return(((some_bool) ? (true) : (false)));

more falafel please
Feb 26, 2005

forums poster

floWenoL posted:

I don't know if you're being intentionally obtuse, but the idea is to use pointers (and not references) only for output parameters.

So you never use pointers for other parameters?

more falafel please
Feb 26, 2005

forums poster

floWenoL posted:

No it doesn't. That's silly.

Have fun with that.

mustDeref() owns you

more falafel please
Feb 26, 2005

forums poster

I'll think about using anything but Perforce when anything but Perforce can handle head revisions with 100+ GB of binary assets without making GBS threads itself, and has a GUI and easy integration with other tools (modeling packages, homebrew tools, etc) that make it so artists will ever be capable of using it.

more falafel please
Feb 26, 2005

forums poster

Captain Capacitor posted:

It's odd you say that, because I find that Perforce has some of the best developer tools available, and a decent Eclipse plugin to boot. However, their unique nomenclature was the worst part for me. The company I was working at was migrating away from it to Mercurial

You mean like "depot", "changelist", "integrate", "clientspec", etc?

more falafel please
Feb 26, 2005

forums poster

ratbert90 posted:

Except in some very rare cases, with C++ >= 14 you shouldn't manage memory.

Using std::unique_ptr and std::shared_ptr does not mean that you're "not managing memory." Those are tools to manage memory, which make it easier to write code that explicitly defines lifetime and ownership and avoid mistakes, and they're extremely useful, but saying "you don't need to manage memory in C++ >= 14" is the same as saying "you don't need to manage memory in mark-and-sweep GC'd languages". Of course you do, you just use different tools to do it. If you don't understand how new and delete work and scope/lifetime/ownership, you're going to have just as nasty bugs using smart pointers (because you're going to use them wrong)

more falafel please
Feb 26, 2005

forums poster

ratbert90 posted:

Back in my day we wrote to the framebuffer directly! No bullshit fancy graphical APIs for me!

The framebuffer is a fancy graphical API.

more falafel please
Feb 26, 2005

forums poster

I'm not a graphics programmer but I've been in AAA games for 14 years and my general sense of things is that graphics programmers would prefer their platform APIs to be as low level as possible and handle things in the abstraction layer like Unreal's RHI. The original DX11 driver on XB1, for instance, was stupid slow in terms of how often it would just flush state doing "normal" things. Moving to DX12 was obviously a lot of work but makes things much more versatile.

more falafel please
Feb 26, 2005

forums poster

The game industry just uses VS. The last platform where you didn't use VS was the PS2, which used MetroWerks CodeWarrior. The one thing it's not good at is understanding C++ when build options aren't defined through project properties (because the project is built with CMake or basically any other external build system). This is basically all games, though. It's sort of impossible, though -- how can visual studio know that the external build tool is going to add "/DFOOBAR" to your compile command line because of a conditional?

more falafel please
Feb 26, 2005

forums poster

Nth Doctor posted:

Oh poo poo I used to use CodeWarrior in my High School C++ class. Thanks for reminding me of something I haven't thought about in nearly two decades.

Only real AP kids remember AquaFish.cpp

more falafel please
Feb 26, 2005

forums poster

I just wish compilers would standardize #pragma optimization settings, since all the major ones support them, so for crossplatform projects you just end up writing a platform-defined macro that looks dumb. They largely all standardized on #pragma once, there's precedent.

more falafel please
Feb 26, 2005

forums poster

the best work chat notification is

"hey"
...
...
...
Person is typing...
...
...
...
...
...
"i have a question for you"

more falafel please
Feb 26, 2005

forums poster

SupSuper posted:

I actually prefer the introductory "hello" to check when the other party is available. If it's an involved question, it's gonna take some back-and-forth so I'd prefer that both sides be present, rather than constantly missing each other with hourly gaps between messages while I have to remember what the question is all over again. Likewise if I see a "hello" it gives me a buffer to reply when I have time, instead of being immediately compelled to drop everything to solve a question.

Maybe this could be solved by proper IM "status" to indicate when you're available for questions, instead of everyone being Away/DND/Invisible 24/7 to hide from coworkers they don't like. :v:

"Hey, I have a couple of questions about the flobnobber, can you hit me up when you have a minute to chat?" and optionally "It's urgent/blocking/etc" or "Whenever you get time, it's not critical right now"

more falafel please
Feb 26, 2005

forums poster

Dumb Lowtax posted:

my windows search does the same thing for some windows feature that I invoke all the time, can't remember what. exact match = like the third result down

"Map network drive" does this for me

more falafel please
Feb 26, 2005

forums poster

Hammerite posted:

I don't understand what you're saying here either (why would increasing the amount of tuition students receive result in a lowered graduation rate?) but the conversation has moved on and it was tenuously relevant anyway, so never mind.

The more tuition costs, the more students will decide they can't afford it when they have some kind of financial hardship

more falafel please
Feb 26, 2005

forums poster

Dumb Lowtax posted:

a childhood friend unironically shared this on fb



you shouldn't be friends with homestucks

more falafel please
Feb 26, 2005

forums poster

Osmosisch posted:

Tuition literally means 'being taught' - where do you think the term 'tuition fees' came from? They're the fees you pay for tuition (being taught). By a tutor.

This makes sense, I guess, but I've literally never heard the term "tuition" referring to anything other than the money you pay to be able to attend classes and receive grades. That of course doesn't include the fees, or the room and board if you want to live on campus, or the books.

more falafel please
Feb 26, 2005

forums poster

Thermopyle posted:

What words "literally" mean quite often tells you little about their meaning in actual, common usage.

Mind literally blown

more falafel please
Feb 26, 2005

forums poster

Volmarias posted:

This is the real answer. Your IDE should be warning you "hey chief, this is an assignment, you sure you want to do that?"

With sensible warning settings modern C++ compilers do that. IDE support is great, but that shouldn't ever see a binary anyway.

more falafel please
Feb 26, 2005

forums poster

Thermopyle posted:

I've been hearing for what seems like decades from perl and php apologists about how "modern perl/php is all a-ok you just have to do x, y, and z".

To be fair, that's what we say in C++-land too.

more falafel please
Feb 26, 2005

forums poster

Volmarias posted:

"garbage collection hobbles new languages" is one heck of a take.

A "systems programming" language with mandatory GC is worthless from the jump

more falafel please
Feb 26, 2005

forums poster

Falcorum posted:

As mentioned, "auto blah = bleh" makes a copy so it can be pretty expensive. The most common issue is using it in "for (auto blah : bleh)" which may mean you could be doing a lot of expensive copies at once.

That doesn't apply if you're just dealing with elementary types like int, bool, etc, since those are cheap to copy, but for anything larger/more complex you'd probably want to use const auto& instead. However to add to the confusion:

code:
int x = 5;

int& y = x;
auto n = y; // auto is deduced as "int"

int* z = &x;
auto m = z; // auto is deduced as "int*"
auto* l = z; // auto is deduced as "int*"

Christ, I somehow didn't realize that auto would deduce to the base type and cause a copy. I've written for (auto member : members) quite a bit.

more falafel please
Feb 26, 2005

forums poster

I've never written a pascal program in my life but I read basically every word of the Inside Macintosh books that I found on CD-ROM at the local used CD/game/movie store/LAN center for $5 while I tried to write actual Mac apps in C that I learned enough pascal to get by, and honestly most of that pascal was just putting together param structs to pass to OS functions (I was going to say kernel, but old macOS wasn't a kernel at all)

more falafel please
Feb 26, 2005

forums poster

Nth Doctor posted:

See year is annoyingly precise here...


It must be poking fun.

because a year is closer to 365.24 than 365.25

you can't forget about the skipped leap year in tested divisible by 100 and the skipped-skipped leap year in years that are divisible by 400, sucka
:cmon:


This is extremely funny to me because as someone who took an intro CS class I definitely know the skip 100 unless it's 400 rules about leap years, but it'll almost certainly never come up for me in the real world, unless i live to 115

Adbot
ADBOT LOVES YOU

more falafel please
Feb 26, 2005

forums poster

ulmont posted:

It came up for the older crowd in 2000.

... this was exactly my point, that unless i live until 2100, leap years are just every four years, since the only century mark I'm likely to be alive for was divisible by 400

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply