The Nightstar Zoo

Nightstar IRC Network - irc.nightstar.net
It is currently Sat Jul 22, 2017 1:56 pm

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Fri Oct 07, 2005 7:33 pm 
Recently hacked a simple Julia fractal generator together over the space of about three days. The resulting source code is probably a litany of How Not To Do It examples, written in C++. For example, here are some of the screwier bits:

Code:
const int set_xsize=600;
const int set_ysize=800;   // for some reason I'm too lazy to work out
const float rangex=6;      // x and y have been swapped and mixed up
const float rangey=8;      // all over the damn place.
const float offsetx=0;      // meh, whatever.
const float offsety=0;

Laziness is a virtue, right? RIGHT?

Code:
   outbmp.open("out.bmp", ios::out | ios::binary | ios::trunc);
   if (! outbmp.is_open())
      { cout << "BALLS!\n"; return (1); }

Note the sucky indentation style and the extra insightful error message.

Code:
//   DOT dotmap [set_xsize][set_ysize];
//   *ahem* STACK OVERFLOOOOWWWW!   
//   I *really* ought to be using a dynamic variable here
//   But the voodoo chicken gods don't like that for some reason
//   Okay, I do actually know how to do it properly
//   But I'm too lazy and hey, it's only a 200 to 1600 kilobyte array.
//   That's WELL within the acceptable limits for a global variable, right?
//   bwahaahahahahah!

You may note that, aside from the blatant use of the wrong damn tool for the job, I also abuse C++ style comments horribly.

Code:
         intensity=0;
         COMPLEX zee(xcoord,ycoord);
         COMPLEX ecs(xcoord,ycoord);
         while ( ((float)zee <= 10000.0f) && (intensity < 25) )
         {
            intensity++;
            zee = zee * zee;
            zee = zee + ecs;
/* additional frobberisation commands go here */
         }

This is probably the cleanest bit of the entire codebase. Except, of course, if one notes the style of comment used...

Code:
/*   outbmp.write((char*)&heada,14);
THIS ^^ is what the code is supposed to be.
BELOW is an ugly hack that I've had to implement
because for some FUCKING REASON this GOD DAMN MOTHERFUCKING
PIECE OF HORSE SHIT IS FUCKING PUTTING THE FUCKING STRUCTS
TOGETHER IN THE WRONG *FUCKING ORDER* AARWBGUIQEA FUCKING USELESS
FUCKING PIECE OF FUCKING SHIT DIE YOU GNU SLUTS DIE DIE DIE DIEDIE
IT'S SUPPOSED TO FUCKING WELL DO WHAT IT SAYS IN THE
FUCKING SOURCE CODE YOU BASTARD WANKERS NOT WHAT THE FUCKIING COMPLIER FEELS LIKE FUCKI DOING TO DAY arwt ej */
   outbmp.write((char*)&heada,2);
   outbmp.write(((char*)&heada+4),10);
   outbmp.write(((char*)&heada+2),2);
   outbmp.write((char*)&headb,40);

Good news is, I'm actually using the right type of comment for the job this time around. Bad news is, I'm using a screwy hack because I can't figure out why GCC keeps putting my structs together in a completely different order to that specified in the header file.

Code:
             float getx(void);  // buggered if I can think of
             float gety(void);  // any good reason to use these ^_^

I'm also horribly cheeky.

Discuss. (Also, does anyone know why GCC might be putting a struct together in some completely different order to that specified in my header files? This is bordering on a hair-rippy-out magnitude annoyance.)


Top
  
 
PostPosted: Sat Oct 08, 2005 3:40 pm 
MineFelinePossesseth wrote:
Code:
/*   outbmp.write((char*)&heada,14);
THIS ^^ is what the code is supposed to be.
BELOW is an ugly hack that I've had to implement
because for some FUCKING REASON this GOD DAMN MOTHERFUCKING
PIECE OF HORSE SHIT IS FUCKING PUTTING THE FUCKING STRUCTS
TOGETHER IN THE WRONG *FUCKING ORDER* AARWBGUIQEA FUCKING USELESS
FUCKING PIECE OF FUCKING SHIT DIE YOU GNU SLUTS DIE DIE DIE DIEDIE
IT'S SUPPOSED TO FUCKING WELL DO WHAT IT SAYS IN THE
FUCKING SOURCE CODE YOU BASTARD WANKERS NOT WHAT THE FUCKIING COMPLIER FEELS LIKE FUCKI DOING TO DAY arwt ej */
   outbmp.write((char*)&heada,2);
   outbmp.write(((char*)&heada+4),10);
   outbmp.write(((char*)&heada+2),2);
   outbmp.write((char*)&headb,40);

Good news is, I'm actually using the right type of comment for the job this time around. Bad news is, I'm using a screwy hack because I can't figure out why GCC keeps putting my structs together in a completely different order to that specified in the header file.


It looks like there's two fields of size 2, and it's putting them into the same word to save space. Does the definition specify "packed", or does the build tool pass "-fpack-struct" to GCC?

Wouldn't it be easier to make a serialization function (or even make it a class) so that you can write by field name and never have to worry about it?

Doing things by offset is tricky business no matter how you do it. Even though you want the binary representation to be the same in the file, endianess, size, and padding can change on different architechures.


Top
  
 
PostPosted: Sat Oct 08, 2005 8:09 pm 
Offline
Nightstar Graveyard Daemon
User avatar

Joined: Mon Jun 03, 2002 8:30 pm
Posts: 1071
Location: Wouldn't you rather observe my Velocity?
MineFelinePossesseth wrote:
Code:
/*   outbmp.write((char*)&heada,14);
THIS ^^ is what the code is supposed to be.
BELOW is an ugly hack that I've had to implement
because for some

(astoundingly foul yet really funny pottymouthed rant snipped)

*/


I needed this laugh. Thank you.

I have done this. I've also used variable names in that same vein. I checked in a bit of code once at Acclaim with a variable name that was about 300 characters long. It was a temporary variable needed because another programmer wrote a get method that took a pointer to int and returned void. The variable name explained all if this and then, at great length, detailed my position on this kind of programming in general before concluding with some rather graphic conjectures about the other programmer's heritage and anatomy.


Top
 Profile  
 
PostPosted: Sat Oct 08, 2005 9:28 pm 
anthonyr wrote:
It looks like there's two fields of size 2, and it's putting them into the same word to save space. Does the definition specify "packed", or does the build tool pass "-fpack-struct" to GCC?

Wouldn't it be easier to make a serialization function (or even make it a class) so that you can write by field name and never have to worry about it?

Doing things by offset is tricky business no matter how you do it. Even though you want the binary representation to be the same in the file, endianess, size, and padding can change on different architechures.


The problem is that he's writing what appears to be a BMP file. (Why BMP? Even MSPaint handles GIFs and PNGs these days...) The structure in question implements the BMP header and its fields have to appear in a specific order.

The problem here might be that this is a C++ program, and in C++, a struct is just another name for a class with all fields public. I'd wager that the differences between a C struct and a C++ class make their binary representations incompatible, and wrapping the struct definition in an extern "C" block may fix the problem.


Top
  
 
PostPosted: Sun Oct 09, 2005 1:56 pm 
BeinSane wrote:
The problem is that he's writing what appears to be a BMP file. (Why BMP? Even MSPaint handles GIFs and PNGs these days...) The structure in question implements the BMP header and its fields have to appear in a specific order.


I imagine it's because BMP takes about 5 minutes to implement...

BeinSane wrote:
The problem here might be that this is a C++ program, and in C++, a struct is just another name for a class with all fields public. I'd wager that the differences between a C struct and a C++ class make their binary representations incompatible, and wrapping the struct definition in an extern "C" block may fix the problem.


I don't really know C++ but just doing it by field name in a serialization function works no matter what's breaking it.


Top
  
 
PostPosted: Sun Oct 09, 2005 7:38 pm 
anthonyr wrote:
BeinSane wrote:
The problem is that he's writing what appears to be a BMP file. (Why BMP? Even MSPaint handles GIFs and PNGs these days...) The structure in question implements the BMP header and its fields have to appear in a specific order.


I imagine it's because BMP takes about 5 minutes to implement...

Or three days, if you happen to be an utter n00blet with a headache, like me... :roll:

anthonyr wrote:
MineFelinePossesseth wrote:
Code:
/*   outbmp.write((char*)&heada,14);
THIS ^^ is what the code is supposed to be.
BELOW is an ugly hack that I've had to implement
because for some FUCKING REASON this GOD DAMN MOTHERFUCKING
PIECE OF HORSE SHIT IS FUCKING PUTTING THE FUCKING STRUCTS
TOGETHER IN THE WRONG *FUCKING ORDER* AARWBGUIQEA FUCKING USELESS
FUCKING PIECE OF FUCKING SHIT DIE YOU GNU SLUTS DIE DIE DIE DIEDIE
IT'S SUPPOSED TO FUCKING WELL DO WHAT IT SAYS IN THE
FUCKING SOURCE CODE YOU BASTARD WANKERS NOT WHAT THE FUCKIING COMPLIER FEELS LIKE FUCKI DOING TO DAY arwt ej */
   outbmp.write((char*)&heada,2);
   outbmp.write(((char*)&heada+4),10);
   outbmp.write(((char*)&heada+2),2);
   outbmp.write((char*)&headb,40);

Good news is, I'm actually using the right type of comment for the job this time around. Bad news is, I'm using a screwy hack because I can't figure out why GCC keeps putting my structs together in a completely different order to that specified in the header file.


It looks like there's two fields of size 2, and it's putting them into the same word to save space. Does the definition specify "packed", or does the build tool pass "-fpack-struct" to GCC?

Wouldn't it be easier to make a serialization function (or even make it a class) so that you can write by field name and never have to worry about it?

Doing things by offset is tricky business no matter how you do it. Even though you want the binary representation to be the same in the file, endianess, size, and padding can change on different architechures.

Pray tell precisely what you mean by a, "serialization function," in this particular context. Please pay attention to the fact that I am indeed an utter n00blet at making things work in general. :)
Also, I'm not *explicitly* passing -fpack-struct to GCC... unless of course some other part of the toolchain might be doing so without telling me? Just to be on the safe side, could I please ask what is the parameter I'd have to give in order to make absolutely certain that it's NOT packing the struct(s)?

Thanks in advance.


Top
  
 
PostPosted: Sun Oct 09, 2005 7:51 pm 
Offline
Nightstar Graveyard Daemon
User avatar

Joined: Mon Jun 03, 2002 8:30 pm
Posts: 1071
Location: Wouldn't you rather observe my Velocity?
MineFelinePossesseth wrote:
Also, I'm not *explicitly* passing -fpack-struct to GCC... unless of course some other part of the toolchain might be doing so without telling me? Just to be on the safe side, could I please ask what is the parameter I'd have to give in order to make absolutely certain that it's NOT packing the struct(s)?


You know, your problem description has really had me scratching my head. According to my calculations, your bug is not actually happening. :-)

Could you post the code somewhere? The complete test file, along with any make files, the expected output and buggy output? If you lack a place to post it, email it to me (forum username at nightstar.net) and I'll post it on the zoo somewhere.


Top
 Profile  
 
PostPosted: Mon Oct 10, 2005 3:19 pm 
MineFelinePossesseth wrote:
Pray tell precisely what you mean by a, "serialization function," in this particular context. Please pay attention to the fact that I am indeed an utter n00blet at making things work in general. :)


Basically a serialization function turns something into a stream of bytes suitable for writing to file or sending across a network. If you use field names instead of offsets you'll get whatever order you want regardless of what the order is, you can leave out things like pointers that don't belong in files, and then it can be in a black box that you don't have to worry about anymore.

MineFelinePossesseth wrote:
Also, I'm not *explicitly* passing -fpack-struct to GCC... unless of course some other part of the toolchain might be doing so without telling me? Just to be on the safe side, could I please ask what is the parameter I'd have to give in order to make absolutely certain that it's NOT packing the struct(s)?


I think it might do it if you set the optimizations high enough. As a rule, don't go above -O2. I don't know specifically because always have problems above -O2 and therefore never do it.


Top
  
 
PostPosted: Mon Oct 10, 2005 6:35 pm 
anthonyr wrote:
MineFelinePossesseth wrote:
Pray tell precisely what you mean by a, "serialization function," in this particular context. Please pay attention to the fact that I am indeed an utter n00blet at making things work in general. :)


Basically a serialization function turns something into a stream of bytes suitable for writing to file or sending across a network. If you use field names instead of offsets you'll get whatever order you want regardless of what the order is, you can leave out things like pointers that don't belong in files, and then it can be in a black box that you don't have to worry about anymore.

So, instead of: (transposed)
Code:
HEADER heada;
INFOHEADER headb;

heada.size = blah;
heada.offset = blah blah;
heada.whatever = whatever else;
headb.something = foo;
headb.bar = baz;

outbmp.write ((char*)&heada, 14);
outbmp.write ((char*)&heada,40);


You're suggesting I instead do something like:
Code:
HEADER heada;
INFOHEADER headb;

heada.size = blah;
heada.offset = blah blah;
heada.whatever = whatever else;
headb.something = foo;
headb.bar = baz;

outbmp.write ((char*)&heada.thingA, 4);
outbmp.write ((char*)&heada.thingB, 4);

That about right? Sounds more sensible than what I'm doing right now, anyway. Apologies for the fact that the above code is a pile of horse crap, I'm far too lazy to put in real variable names for it all.

Quote:
MineFelinePossesseth wrote:
Also, I'm not *explicitly* passing -fpack-struct to GCC... unless of course some other part of the toolchain might be doing so without telling me? Just to be on the safe side, could I please ask what is the parameter I'd have to give in order to make absolutely certain that it's NOT packing the struct(s)?


I think it might do it if you set the optimizations high enough. As a rule, don't go above -O2. I don't know specifically because always have problems above -O2 and therefore never do it.

I'm not optimising at all right now... though I'll have to change that fact later in order to cut down the amount of time that rendering a huge animated one takes.

Chalain wrote:
MineFelinePossesseth wrote:
Also, I'm not *explicitly* passing -fpack-struct to GCC... unless of course some other part of the toolchain might be doing so without telling me? Just to be on the safe side, could I please ask what is the parameter I'd have to give in order to make absolutely certain that it's NOT packing the struct(s)?


You know, your problem description has really had me scratching my head. According to my calculations, your bug is not actually happening. :-)

Could you post the code somewhere? The complete test file, along with any make files, the expected output and buggy output? If you lack a place to post it, email it to me (forum username at nightstar.net) and I'll post it on the zoo somewhere.

No worries man, it doesn't actually happen according to my calculations either :D
I'll try bugfixin' a la serialisation (there are one or two other little bugs hiding about the place that might also be a result of these struct related woes) and then if that doesn't work I'll .tar.gz it all and ftp it somewhere. If it does work, then I'll do the same thing, only I'll add smiley faces and a readme.txt to it :)


Top
  
 
PostPosted: Mon Oct 10, 2005 8:53 pm 
MineFelinePossesseth wrote:
That about right? Sounds more sensible than what I'm doing right now, anyway.


Also there's a sizeof operator so you don't have to hardcode the size. It's also helpful to use a type that's the same on every architechture in a case like yours. Instead of "short int", you can use "int16_t". Also, you should make sure the data is in the correct endian format, eg if it has to run on a Mac or something.

These should be regarded as necessary even if you're pretty sure it won't leave that OS or architechture. Without caution to make sure everything is well defined, code produces weird bugs, as you've seen. Projects that no one is ever going to see aren't an opportunity to slack of with good style. They're a chance to practice good style.

http://www.fit.hcmuns.edu.vn/~dxquang/Teaching/Ctdl1/References/c.pdf

It's helpful to read this cover to cover, and have a good grasp of C before you take C++ too seriously. I've seen many a programmer get sucked into C++, and then have a hard time with the underlying principals because there's too much magic in the language and you just have to give up and accept it. In C, there's very little magic and what little there is is exposed through libraries that must be explicitly called rather than language features that "just work". Exclusively C++ programmers also tend to have trouble with other languages because they want to turn everything else into C++, it's the only style they know. If you start with C, then you have a solid foundation but the language isn't powerful enough to do everything by itself so you learn other things as optional extensions rather than a mandatory minimum.


Top
  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 2:31 pm 
Offline
Nightstar Graveyard Daemon
User avatar

Joined: Mon Jun 03, 2002 8:30 pm
Posts: 1071
Location: Wouldn't you rather observe my Velocity?
Oh. My. Crapwacket.

What did you just do? You better tell me what you just did, because I KNOW you did not just point someone to K&R and say they should learn and practice that style.

:P

MineFelinePossesseth: my severe allergic reaction notwithstanding, the K&R book is THE reference to have on learning to program and think in C. It's worth reading. Just don't forget to ALSO practice good style. :-)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 3:18 pm 
On the subject of programmers trying to turn everything into C++: No. :) It's true for most new programmers that they try to use the paradigms they learned in their first language. This is most definitely not unique to new C++ programmers, and is part of the learning process.

However, once you get to a certain point, you learn to think in whatever language you're using, and choose that language based on the problem at hand. Or at least that's my opinion on it.

That's all, mister sweeping generalizations. :)


Top
  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 5:32 pm 
Raif wrote:
However, once you get to a certain point, you learn to think in whatever language you're using, and choose that language based on the problem at hand. Or at least that's my opinion on it.


My point is that C++ seems more likely to make it hard for programmers to break out of that way of thinking. That doesn't mean C++ programmers are always like that, just that it's a greater risk for them when they're getting started.

Upon further consideration, I think it might also be because it attracts programmers that want to learn one language that they can use for everything. That's a very short list, and the others (Java, C#) have significant disadvantages that keep them from being universal.


Top
  
 
 Post subject:
PostPosted: Fri Oct 14, 2005 2:25 am 
Offline
Safari Exhibit
Safari Exhibit
User avatar

Joined: Mon Feb 07, 2005 3:48 am
Posts: 151
Location: Durban, South Africa
Raif wrote:
On the subject of programmers trying to turn everything into C++: No. :) It's true for most new programmers that they try to use the paradigms they learned in their first language. This is most definitely not unique to new C++ programmers, and is part of the learning process.


I managed to avoid this by the simple expedient of learning two "languages" at once (C64 BASIC and LOGO), followed several years later by a bondage and discipline structured language (Pascal). This made it literally impossible to use the same idioms/paradigms/style. Fortunately I survived both and now I'm fairly comfortable with several real languages.

I'm very much a proponent of the "choose the correct language for the job" philosophy. I have had to do *way* too much debugging of code written in inappropriate languages.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group