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
plushpuffin
Jan 10, 2003

Fratercula arctica

Nap Ghost

EpicCodeMonkey posted:

I never understood why the language (or other C-derived languages, for that matter) don't make fall-through legal in switch statements, but require that the last statement in each case be "break", "return", or "continue" - the latter specifying a fallthrough. If anything else is encountered it would be a syntax error. The only downside would be that...

I don't understand why you have a problem with the way it works now. It's more powerful than your idea, because the two case statements subject to the fallthrough don't have to be contiguous, and use of the goto keyword is more consistent and appropriate than continue in this case, anyway (continue being used to skip the remaining statements in a loop).

Look at the first example on this page and tell me it's not more logical and flexible than what you just proposed.

Adbot
ADBOT LOVES YOU

Scaevolus
Apr 16, 2007

EpicCodeMonkey posted:

I never understood why the language (or other C-derived languages, for that matter) don't make fall-through legal in switch statements, but require that the last statement in each case be "break", "return", or "continue" - the latter specifying a fallthrough. If anything else is encountered it would be a syntax error. The only downside would be that:

code:
switch
{
     case 1:
     case 2:
          DoSomething();
}
Would be illegal both due to the missing break at the end, and the two case statements together with no code in between, but you could special-case that. This way there's no way a programmer can accidentally fallthrough, but it's still possible if that is desired.
I like Go's solution:

Expression switches

In an expression switch, the switch expression is evaluated and the case expressions, which need not be constants, are evaluated left-to-right and top-to-bottom; the first one that equals the switch expression triggers execution of the statements of the associated case; the other cases are skipped. If no case matches and there is a "default" case, its statements are executed. There can be at most one default case and it may appear anywhere in the "switch" statement. A missing switch expression is equivalent to the expression true.

In a case or default clause, the last statement only may be a "fallthrough" statement (§Fallthrough statement) to indicate that control should flow from the end of this clause to the first statement of the next clause. Otherwise control flows to the end of the "switch" statement.

The expression may be preceded by a simple statement, which executes before the expression is evaluated.

code:
switch tag {
default: s3()
case 0, 1, 2, 3: s1()
case 4, 5, 6, 7: s2()
}

switch x := f(); {  // missing switch expression means "true"
case x < 0: return -x
default: return x
}

switch {
case x < y: f1()
case x < z: f2()
case x == 4: f3()
}

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
Don't know if this is really a horror but I laughed at it
code:
    int getMonthOfYear(long millis, int year) {
        // Perform a binary search to get the month. To make it go even faster,
        // compare using ints instead of longs. The number of milliseconds per
        // year exceeds the limit of a 32-bit int's capacity, so divide by
        // 1024. No precision is lost (except time of day) since the number of
        // milliseconds per day contains 1024 as a factor. After the division,
        // the instant isn't measured in milliseconds, but in units of
        // (128/125)seconds.

        int i = (int)((millis - getYearMillis(year)) >> 10);

        // There are 86400000 milliseconds per day, but divided by 1024 is
        // 84375. There are 84375 (128/125)seconds per day.

        return
            (isLeapYear(year))
            ? ((i < 182 * 84375)
               ? ((i < 91 * 84375)
                  ? ((i < 31 * 84375) ? 1 : (i < 60 * 84375) ? 2 : 3)
                  : ((i < 121 * 84375) ? 4 : (i < 152 * 84375) ? 5 : 6))
               : ((i < 274 * 84375)
                  ? ((i < 213 * 84375) ? 7 : (i < 244 * 84375) ? 8 : 9)
                  : ((i < 305 * 84375) ? 10 : (i < 335 * 84375) ? 11 : 12)))
            : ((i < 181 * 84375)
               ? ((i < 90 * 84375)
                  ? ((i < 31 * 84375) ? 1 : (i < 59 * 84375) ? 2 : 3)
                  : ((i < 120 * 84375) ? 4 : (i < 151 * 84375) ? 5 : 6))
               : ((i < 273 * 84375)
                  ? ((i < 212 * 84375) ? 7 : (i < 243 * 84375) ? 8 : 9)
                  : ((i < 304 * 84375) ? 10 : (i < 334 * 84375) ? 11 : 12)));
    }

TasteMyHouse
Dec 21, 2006
Jesus Christ. Where did you find that?

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
It's in JodaTime, https://github.com/JodaOrg/joda-time/blob/master/src/main/java/org/joda/time/chrono/BasicGJChronology.java

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Hahaha I love the bit shift, it's a little microcosm of everything that is wrong with that function.

tripwire
Nov 19, 2004

        ghost flow

Well, beats Calendar I guess

Beef
Jul 26, 2004

Aleksei Vasiliev posted:

Don't know if this is really a horror but I laughed at it

I have no notion that my code gets compiled and optimized, so here is an obtuse series of nested ternary-notation comparing magic numbers.

Standish
May 21, 2001

quote:

If the shell is written in C++, why not just export its base classes?

Second of all, who says the shell is written in C++? As it happens, when IShell­Folder was introduced in Windows 95, the entire shell was written in plain C. That's right, plain C. Vtables were built up by hand, method inheritance was implemented by direct replacement in the vtable, method overrides were implemented by function chaining, multiple inheritance was implemented by manually moving the pointer around.
code:
const IShellFolderVtbl c_vtblMyComputerSF =
{
 MyComputer_QueryInterfaceSF,
 MyComputer_AddRefSF,
 MyComputer_ReleaseSF,
 MyComputer_ParseDisplayName,
 ... you get the idea ...
};

const IPersistFolderVtbl c_vtblMyComputerPF =
{
 MyComputer_QueryInterfacePF,
 MyComputer_AddRefPF,
 MyComputer_ReleasePF,
 MyComputer_Initialize,
};

struct MyComputer {
 IShellFolder sf;
 IShellFolder pf;
 ULONG cRef;
 ... other member variables go here ...
}

MyComputer *MyComputer_New()
{
 MyComputer *self = malloc(sizeof(MyComputer));
 if (self) {
  self->sf.lpVtbl = &c_vtblMyComputerSF;
  self->pf.lpVtbl = &c_vtblMyComputerPF;
  self->cRef = 1;
  ... other "constructor" operations go here ...
 }
 return self;
}

// sample cast
MyComputer *pThis;
IPersistFolder *ppf =  &pThis->pf;

// sample method call
hr = IShellFolder_CompareIDs(psf, lParam, pidl1, pidl2);
// which expands to
hr = psf->lpVtbl->CompareIDs(psf, lParam, pidl1, pidl2);

// sample forwarder for multiply-derived method
HRESULT STDCALL MyComputer_QueryInterfacePF(
    IPersistFolder *selfPF, REFIID riid, void **ppv)
{
 MyComputer *self = CONTAINING_RECORD(selfPF, MyComputer, pf);
 return MyComputer_QueryInterfaceSF(&self->sf, riid, ppv);
}
So one good reason why the shell didn't export its C++ base classes was that it didn't have any C++ base classes.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Aleksei Vasiliev posted:

Don't know if this is really a horror but I laughed at it

For the record: while this code should certainly be using named constants, and I personally would write it with if instead of nested conditionals, the three explicit optimizations here are worthwhile, and a date library is a good candidate for this degree of tuning.

First, the compiler is very unlikely to be able to do the range analysis necessary to figure out that it can use 32-bit arithmetic here, but doing so is a substantial speedup on a 32-bit architecture.

Second, if the code were written to divide by 86400000 instead of 1024, a good compiler would do that division with multiplies, but it would probably be blocked (again, by inadequate knowledge of the range constraints) from factoring out 84375 and getting all the way to this code.

Third, while some compilers might convert a sequence of conditions into a binary search, many wouldn't, and that's not necessarily just a missing optimization: there's a lot of code that's structured so that the more likely cases are checked first.

So yeah, the style could be a lot better, but the ideas are good.

Opinion Haver
Apr 9, 2007

How often do you need to go from millis to months in a tight loop?

SlightlyMadman
Jan 14, 2005

yaoi prophet posted:

How often do you need to go from millis to months in a tight loop?

Even if you somehow did end up in a situation like this, you'd probably be better off optimizing the loop itself. If you really and truly need to do some millions of month look-ups, you'd probably still be better off just caching them.

HORATIO HORNBLOWER
Sep 21, 2002

no ambition,
no talent,
no chance

Standish posted:

Raymond Chen's blog

Where's the horror? I write OO in C all the time and while I often wish I were doing it in a language that made it easier, it remains a great way to organize and think about your code. Anyone who has read or written code that does COM in C has seen stuff that looks practically identical to this. It may seem silly to you but Chen's justifications are valid ones, especially when you consider the constraints of the early 90s.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

SlightlyMadman posted:

Even if you somehow did end up in a situation like this, you'd probably be better off optimizing the loop itself. If you really and truly need to do some millions of month look-ups, you'd probably still be better off just caching them.

This criticism is misplaced. If you were rolling your own milli-to-month converter as a tiny part of a larger project, I agree that your time would probably be better spent optimizing something else. It is not at all obvious that this is equally true of the maintainer of a date/time library.

Analogously, an application programmer should not start optimizing their code by rewriting malloc, but criticizing the libc maintainers for doing so is asinine.

And yes, I can imagine someone wanting to decompose timestamps into dates in a fairly tight loop.

SlightlyMadman
Jan 14, 2005

This is all theoretically true, but libc maintainers are hopefully smart enough to make their own decisions rather than be swayed by the opinions of a guy on the internet. Everyone else happens to fall into the "not a libc maintainer" category, and probably has no business writing code like that.

TasteMyHouse
Dec 21, 2006
If they need performance, why are they writing in Java in the first place? :smugC++:

epswing
Nov 4, 2003

Soiled Meat
This is the result of the #cobol irc channel being asked to collaboratively write fizzbuzz:

code:
Write a program that prints the numbers from 1 to 100. But for multiples 
of three print "Fizz" instead of the number and for the multiples of 
five print "Buzz". For numbers which are multiples of both three and 
five print "FizzBuzz".

public static virtual protected volatile void fizzbuzz() {
    /*TODO: implement this*/
    take_a_big_dump();
    how do i set my name :/
    Right side, bro does it show uP/
    im the one that wrote penus lol
    int num = 1;
    ggggggggggggggggggggg; //Syntax error for some reason?
    // what is all this bullshit in my fizzbuzz thing
}

print("PENUS")
print("PENUS")
print("PENUS")
print("PENUS")
print("PENUS")
print("PENUS")
print("PENUS")
print("PENUS")
print("PENUS")
print("PENUS") pretty sure you're writing this wrong. yeah it should be printf



while True:
    print("poops")

const bool is_dumb = true; // Never change this
// WHAT THE gently caress GUYS
// nvm


PYTHON:
[not i%15and"fizzbuzz" or not i%5and"buzz" or not i%3and"fizz" or i for i in range(1,100)] 

# Why doesn't this work????
int x = $GET("size");
let foo = malloc(x);
if (sizeof(foo) > INT_MAX)
    raise Error("you exceeded INT_MAX!!! dumbass") /*burn*/
    
/*TODO: work in a "Util" into this class title somehow*/    
JAVA:
class FizzBuzzFactoryFactoryManagerGeneratorHelper {
};

# The best script
while True:
    print random.choose(["Millions", "Hundreds", "Thousands"]) + \
          " of "+random.choose(["hard", "throbbing", "glistening"]) + \
          " " + random.choose(["cocks", "boners", "dicks", "pricks"]) + \
          " slapping you gently in the "+random.choose(["mouth", "face", "lips", "rear end"]) + "."

# The bester script

while True:
    print "{0} of {1} {2} slapping you gently in the {3}".format(
        random.choice(["Millions", "Hundreds", "Thousands"]), 
        random.choice(["hard", "throbbing", "glistening"]),
        random.choice(["cocks", "boners", "dicks", "pricks"]), 
        random.choice(["mouth", "face", "lips", "rear end"]))
    
/* needs a generic PenisFactoryFactory */

class PenisFactoryFactory:
    def __init__(self):
        self.dongfact = PenisFactory()
    def ReturnDongs(self):
        return self.dongfact

Zombywuf
Mar 29, 2008

Whole lotta pent up homosexuality in that code. Just sayin'.

Catalyst-proof
May 11, 2011

better waste some time with you

epswing posted:

code:
while True:
    print "{0} of {1} {2} slapping you gently in the {3}".format(
        random.choice(["Millions", "Hundreds", "Thousands"]), 
        random.choice(["hard", "throbbing", "glistening"]),
        random.choice(["cocks", "boners", "dicks", "pricks"]), 
        random.choice(["mouth", "face", "lips", "rear end"]))

PEP3101 represent.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

SlightlyMadman posted:

This is all theoretically true, but libc maintainers are hopefully smart enough to make their own decisions rather than be swayed by the opinions of a guy on the internet. Everyone else happens to fall into the "not a libc maintainer" category, and probably has no business writing code like that.

So, to paraphrase, your opinions are above reproach because anyone smart enough to not need them is smart enough to ignore you.

dancavallaro
Sep 10, 2006
My title sucks
Everyone here realizes that Java's date/time implementation is terrible, and JodaTime is an extremely popular and widely-used date/time library, right?

SlightlyMadman
Jan 14, 2005

rjmccall posted:

So, to paraphrase, your opinions are above reproach because anyone smart enough to not need them is smart enough to ignore you.

Something like that. At least I'm not a dick, though.

TasteMyHouse
Dec 21, 2006

dancavallaro posted:

Everyone here realizes that Java's date/time implementation is terrible, and JodaTime is an extremely popular and widely-used date/time library, right?

I'm sure it performs great but god drat is that ugly.

tef
May 30, 2004

-> some l-system crap ->

SlightlyMadman posted:

Something like that. At least I'm not a dick, though.

No, you're a moron :3:

Sign
Jul 18, 2003

Internet Janitor posted:

Do they specify a level of granularity? Public methods (easy and a good idea), Lines (arbitrary), Code paths (gently caress)?

Code paths. On the plus side I learned an interesting little bit about java byte code construction
code:
try{
  thingThatThrowsIOException();
}
catch(IOException e){
}
finally{
// something here
}
How many ways can you get into the finally block? 3, the third is for a different exception besides IO

Anybody looking for someone in the DC area to not do government work?

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Sign posted:

Code paths. On the plus side I learned an interesting little bit about java byte code construction
code:
try{
  thingThatThrowsIOException();
}
catch(IOException e){
}
finally{
// something here
}
How many ways can you get into the finally block? 3, the third is for a different exception besides IO

Anybody looking for someone in the DC area to not do government work?
What did you think the finally clause did?

aleph1
Apr 16, 2004

Sign posted:

Code paths. On the plus side I learned an interesting little bit about java byte code construction
code:
try{
  thingThatThrowsIOException();
}
catch(IOException e){
}
finally{
// something here
}
How many ways can you get into the finally block? 3, the third is for a different exception besides IO

Anybody looking for someone in the DC area to not do government work?

And what do you think happens with:

code:
try {
  foo();
  return 0;
} catch (Exception e) {
} finally {
  System.err.println("bar");
}
(finally always runs unless you manage to crash the JVM or call exit() somewhere)

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

HORATIO HORNBLOWER posted:

Where's the horror? I write OO in C all the time and while I often wish I were doing it in a language that made it easier, it remains a great way to organize and think about your code. Anyone who has read or written code that does COM in C has seen stuff that looks practically identical to this. It may seem silly to you but Chen's justifications are valid ones, especially when you consider the constraints of the early 90s.

Yeah but we're in 2011 and you still need to deal with all this COM bullshit to write a shell extension. It hasn't gotten any better since the late 90's.

pseudorandom name
May 6, 2007

What would you replace it with?

Zombywuf
Mar 29, 2008

pseudorandom name posted:

What would you replace it with?

Bash scripts.

SlightlyMadman
Jan 14, 2005

tef posted:

No, you're a moron :3:

I'd rather work with a mediocre programmer who knows his limits, than a genius who doesn't.

tef
May 30, 2004

-> some l-system crap ->
I suggest learning java and developing middleware. Apart from the limits bit.

Milotic
Mar 4, 2009

9CL apologist
Slippery Tilde

aleph1 posted:

And what do you think happens with:

code:
try {
  foo();
  return 0;
} catch (Exception e) {
} finally {
  System.err.println("bar");
}
(finally always runs unless you manage to crash the JVM or call exit() somewhere)

Cross-thread Thread.Abort() will do the trick as well in .NET 1.0 and 1.1. It's been fixed since .NET 2.0, but TerminateThread can still abort in the middle of a finally block.

e: There's a couple of .NET library calls which can call Thread.Abort if you try to access COM objects in a funny way, which is a bit of a coding horror / annoying as hell.

Sign
Jul 18, 2003

MEAT TREAT posted:

What did you think the finally clause did?

I thought it did that but that it was one block of code from the perspective of coverage. As in it didn't become more than one copy of the same stuff in byte code.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Sign posted:

I thought it did that but that it was one block of code from the perspective of coverage. As in it didn't become more than one copy of the same stuff in byte code.

It is, in fact, one block of code. The finally block itself is implemented as a subroutine (using jsr/ret), and anywhere control leaves the corresponding try block, that subroutine gets called first.

But if you're going for full test coverage, you need to test every way you can get into that subroutine, rather than just testing one case and assuming that it works correctly for the others.

w00tz0r
Aug 10, 2006

I'm just so god damn happy.
code:
class A
{
    virtual void Foo() { } 
};

void DoSomething() 
{
    ... 
}

class B : public A 
{ 
    void Foo()
    {
        DoSomething();
    }
} 

class C : public A
{
    void Foo()
    {
        DoSomething();
    }
}
Edit: Found this one after commenting out a call to A::Foo() and finding out that nothing worked anymore. Was really confused as to why commenting out a no-op would break everything.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
So the horror is that you're confused by inheritance and virtual methods?

w00tz0r
Aug 10, 2006

I'm just so god damn happy.

Plorkyeran posted:

So the horror is that you're confused by inheritance and virtual methods?

The horror is that the base has all of it's member functions implemented as no-ops, while the derived classes copy/paste the same implementation for 90% of the code, with no indication that you're even dealing with a polymorphic class.

I guess the example I posted really didn't give a sense of the scope to which everything was copied.

PrBacterio
Jul 19, 2000

w00tz0r posted:

The horror is that the base has all of it's member functions implemented as no-ops
That's what we in the industry like to call an "interface," and it's what the derived classes are "copying" (actually *implementing*, since, as the empty methods from the base class don't actually *do* anything there isn't any code being duplicated from there). The horror here being that all of these empty virtual methods from the base class should have been declared as abstract virtual methods (ie. virtual foo() = 0;) instead.

Adbot
ADBOT LOVES YOU

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

PrBacterio posted:

That's what we in the industry like to call an "interface," and it's what the derived classes are "copying" (actually *implementing*, since, as the empty methods from the base class don't actually *do* anything there isn't any code being duplicated from there). The horror here being that all of these empty virtual methods from the base class should have been declared as abstract virtual methods (ie. virtual foo() = 0;) instead.

Not according to what he said -- they're duplicating functionality. The common functionality needs to be implemented in the base class in a non-virtual method, which possibly calls some virtual/abstract methods that contain differing, implementation-specific code.

Of course, I'm not sure what you're calling an "interface" there, since there are no interfaces anywhere in the example, and an interface isn't appropriate for what he was talking about anyway.

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