UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#51 2009-06-19 10:10 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: STL for Tree

which makes it more obvious that you are deliberately ignoring the argument, and didn't just botch an if statement.

Well, what we all really do, as sort of an informal standard, is:

if (unused_arg)
    ; /* shut the stupid compiler up! */

Which kind of makes it clear that it's deliberate, too... ;-)

I'm not sure why we don't use the void cast trick; it's probably because the original
compiler we had to use on QNX2 definitely wouldn't have supported that (it was a
K&R era compiler), and it just became habit... *shrug*

I guess that all depends on what your definitions of "bad things" and "perfectly fine behavior" are.

Yeah, obviously...  And, that's probably why GCC is so damn configurable in its
warnings, letting you turn on/off any individual ones you prefer: because everyone's
tastes are different...

Without those warnings it would have taken me longer to detect and correct my error.

*shrug*  By that logic, it sounds like you'd welcome other "helpful" warnings, such
as "Hey, this function doesn't look long enough to me!  Are you sure you really
implemented everything you meant to??", or "Are you sure you really want to be
accessing that global/static variable?  Your function has arguments: use them to
pass in data instead!", or "Your variable names are too damn similar; change them
to something really unique instead!", etc... ;-)

At some point, the compiler has to accept that you actually know what you're doing,
and yes you really meant to do that, or else it would have to complain about every
single line of code, since MAYBE you made a bug there...  If it's a normal, standard
thing that everyone needs to regularly do (have unused args in their functions, cast
to/from void*, etc.), the assumption SHOULD be that you did it intentionally, not that
you fucked up, unless there is some other evidence of that...

Or, you could consider the possibility that the warnings have merit, and change your programming practices to avoid the risks they are trying to warn you about....

How the hell do you possibly "change your programming practices" to avoid something
like unused function arguments?!  It's something that's incredibly common, pretty
much anywhere you have a standard API that you need to conform to...  Because,
the API is usually general enough to accommidate features that you often won't
need...  If you setup a signal handler for a single signal, say SIGCHLD, your handler
must be declared to take the int signal# arg (unless you want to do nasty function
pointer casting), yet you have absolutely NO need for it, since you know what signal
it's handling already...  Are you honestly saying you should do something silly like:

static void child_reaper (int sig)
{
    if (sig == SIGCHLD) {
        /* do the normal reaping... */
    } else {
        die ("Holy shit, your computer is possessed!");
    }
}

All simply to conform my "programming practices" to some stupid compiler's idea of
what is ideal?!

Compiler writers aren't ALL idiots, you know... :^)

No, but compilers all ARE! ;-/

I don't like any programs I use ever thinking they're smarter than I am...  I like them
to be obediant servants, not uptight nannies...  Especially something as generic as
a compiler, which has to process code that can literally be doing ANYTHING, which
the compiler writer(s) maybe could never have even dreamed of at the time...  It can't
possibly know my intent, so it should not presume to give me style advice...  If it sees
a real error, or something truly unusual which could be problematic, then yes tell me
about it...  Referencing an uninitialized variable?  Yes, warn me about that, because
it's highly unlikely I'd intentially want to do that...  (In rare cases, yes, maybe...  In
those rare cases, I can deal with shutting the warning up...  But, set the warnings
so they are tolerable in the USUAL case...)  Passing a number of arguments that
don't match my printf() format string?  Yes, warn me about that, because that's not
something commonly desirable...  But, having an unused function argument?  That's
outrageously common and desirable, and in 99% of cases will be intentional, so
don't fucking warn about that!  The same goes for void* casting, as far as I'm
concerned...

Really? You can't imagine someone typing

If you're foolish enough to name a completely unrelated variable so similarly to
another variable, well the code is going to be hell for any human to follow, so you
probably should change that, anyway...  The problem certainly is NOT the void*, in
that case; the problem is the inappropriate variable name...  The void* complaint
would only help the original programmer who knows why the fuck he used such
stupidly similar variable names for completely unrelated data, and so would maybe
recognize the error...  But, someone else that was trying to modify that code in the
future who got that warning?  They'd likely be confused by the naming, and think the
correct thing to do is just throw the explicit cast in there to shut the compiler up...

Plus, as I said, this has to be a very rare case, indeed...  Surely, the NORMAL case
99% of the time is that when someone assigns either to or from void*, they intended
to do so...  So, it shouldn't warn (or worse, error) on NORMAL behavior, just on the
off chance that maybe this is one of those rare cases where you really didn't intend
to do that...

Offline

#52 2009-06-19 11:46 PM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: STL for Tree

RobSeace;26987 wrote:

some point, the compiler has to accept that you actually know what you're doing

Yup, and so we are really just arguing over where that point should be located.  I have a bit less faith in my ability to avoid mistakes than you do, so I like my compiler to be fussier than you like it.

How the hell do you possibly "change your programming practices" to avoid something like unused function arguments?!

I think we just covered a couple of ways to do that... the (void) cast way works for me.

But, having an unused function argument?  That's outrageously common and desirable, and in 99% of cases will be intentional, so
don't fucking warn about that!  The same goes for void* casting, as far as I'm concerned..

I prefer to be warned, and that way I don't get bit by the other 1% of the cases.  I don't mind having to add a little bit of extra code to shut the compiler up.  YMMV.

Plus, as I said, this has to be a very rare case, indeed...  Surely, the NORMAL case 99% of the time is that when someone assigns either to or from void*, they intended to do so...  So, it shouldn't warn (or worse, error) on NORMAL behavior, just on the off chance that maybe this is one of those rare cases where you really didn't intend to do that...

Rare for you, maybe.  I make mistakes like that probably a couple of times a week, and I'm much happier if they are caught at compile time than at run time.  Maybe I am just error prone, but then again I expect so are a lot of people....

Jeremy

Offline

#53 2009-06-20 01:52 AM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,231

Re: STL for Tree

jfriesne;26984 wrote:

Is he?  How can you be sure?  In a non-trivial function, it's easy to accidentally use one variable when you meant to use another, and accidentally do something you didn't mean to do.  The reason that languages have type systems is to help catch that sort of error.

If that's easy to happen then you should fix the bloody code. Seriously, a
function which is that big that you can't keep track of everything it's doing
is plain bad code. Split it up, add some helper functions, anything. Because
code like that is unreadable and making any mistake is easy.

Not keeping track of the variables is a really serious problem that should
be fixed, not worked around so you can more easily limp along.

But forcing a cast won't fix your problem at all though. Sure, type safetly
is great. Casting is bad because it bypasses the type system. Adding a cast
adds another potential bug, like I explained in my last post. The only
purpose of void* is bypassing the type system and pass along pointers.
Requiring a cast not only bypasses the subtype of the pointer, it bypasses
the whole type system.

I'd agree to that as you as you replace "most of" with "barely any of".  The fact is that without knowing the type of the data that is pointed to, there is almost nothing you can do with the pointer, other than check to see if it's NULL, or hand it to some other bit of code that does know its type.  So if that's not typeless, it's pretty close to it.

Passing it along is what happens a lot. And when you use it, you think
you know what it is. But you use void* mostly when you don't care what
it is, then knowing it's a pointer, any pointer, is enough.

I take your point, but I think your argument is more an argument for avoiding void pointers entirely, since they are inherently unsafe.... :^)

Exactly like you should avoid casting stuff, because both are about
bypassing the type system. But sometimes it's needed or convenient,
and then it's pretty harmless when done well. It's inherently risky,
like unclasping your safety. But sometimes it's needed to get from
one end to the other.

Offline

#54 2009-06-20 02:11 AM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: STL for Tree

i3839;26990 wrote:

Not keeping track of the variables is a really serious problem that should be fixed, not worked around so you can more easily limp along.

When you come up with a fix for human error, let me know... in the meantime I have to limp along knowing that occasionally I will screw things up.  Given that, I'd like the compiler to help me catch as many errors as it can.

But forcing a cast won't fix your problem at all though. Sure, type safety is great. Casting is bad because it bypasses the type system. Adding a cast adds another potential bug, like I explained in my last post. The only
purpose of void* is bypassing the type system and pass along pointers.
Requiring a cast not only bypasses the subtype of the pointer, it bypasses
the whole type system.

Very true, casting is dangerous as well.  But at least when I see code that has explicit unsafe casting in it, I will immediately think "here be dragons".  If the unsafe casting is implicit, it's that much worse, because a quick scan through the code won't even reveal that casting is going on.

Offline

#55 2009-06-20 02:10 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,231

Re: STL for Tree

void SomeFunc()
{
    struct MyType blah;
    struct MyType * p;
    struct MyType * t = &blah;
    void * tt;
    struct MyOtherType * ttt = blah.other;

    p = (struct MyType*)ttt; /* programmer error here! */
    p = ttt;   /* same error, but compiler warns about it. */
}


That said, your example does give one situation where forcing a cast would
help avoiding a bug. Void* is useful, but almost never as a separate variable.
It's either part of a structure or a function parameter. This together with
accidentally using the wrong variable makes the whole scenario even less
likely to happen. The above example is as likely to happen. In either case it's
a class of bugs that's very easy to find and fix, because you get a hard crash
when it happens.

Offline

#56 2009-06-20 06:58 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: STL for Tree

Yup, and so we are really just arguing over where that point should be located. I have a bit less faith in my ability to avoid mistakes than you do, so I like my compiler to be fussier than you like it.

And, like I said, that's why I'm glad GCC is so configurable in its warning system...
Different strokes for different folks...  Now, if only all other compilers were as nice...
I quibble with its choice of defaults, but who really cares, as long as you can turn
them off...  I can live with a mile-long CFLAGS in my Makefiles... ;-)

I think we just covered a couple of ways to do that... the (void) cast way works for me.

But, that's NOT "avoiding" unused arguments; it's kluging around the compiler bitching
about them...  The args are still unused, in any meaningful sense of the word...  You
are just tricking the compiler into believing otherwise, purely to shut it up, and accomplish
absolutely NOTHING else of value from doing so...  You just clutter the code to
satisfy an obnoxiously overzealous compiler...

I prefer to be warned, and that way I don't get bit by the other 1% of the cases.

I find that an utterly insane way of looking at things...  Like I said before, if you get
warnings all the time about normal, correct behavior, eventually you WILL become
desensitized to them, and just start ignoring them, because 99% of the time they
are wrong and you are right...  So, you'll never catch that 1% of the time they happen
to be right and you wrong, because you've become so burned-out by the overwhelming
flood of false-positives prior to that, so you assume this must be another case, and
just slap in the usual kluge-around fix without thinking...

Look at it this way: 99% of the time I dereference a pointer without an explicit NULL
check first, I'm right to do so, because I know it can't be NULL at that point due to
outside code; but, 1% of the time, I've screwed up, and a NULL can slip in...  Would
you really want the compiler to start warning every single time you dereferenced a
pointer, and forced you to always throw in a NULL check around every single one?
If so, we obviously have extremely different tastes about acceptable compiler
behavior...

I don't mind having to add a little bit of extra code to shut the compiler up. YMMV.

I do, because it horribly clutters the code, making it ugly and harder to read for
humans, and provides absolutely ZERO functional benefit...  It merely serves to
correct a fault in the compiler...  The compiler is wrong about your code being a
problem, and should not be complaining; so, you have to kluge around its bugs to
shut it up...  It's as horrible and ugly as any other klugey work-around to buggy
tools/systems/libraries/etc...  Klugey bug work-arounds are never desirable...

Offline

#57 2009-09-08 08:46 AM

dannydesiliva
Guest

Re: STL for Tree

> Is there any STL available for B/B+/B* Tree??or any tree in msvc++?

std::set and std::map are typically implemented as balanced trees -
usually red-black trees. If these are not sufficient for your needs,
you'll have to look for third-party libraries, or roll your own.
--
Igor Tandetnik

Board footer

Powered by FluxBB