POV-Ray : Newsgroups : povray.off-topic : All your radix are belong to us! Server Time
29 Jul 2024 20:24:13 EDT (-0400)
  All your radix are belong to us! (Message 18 to 27 of 27)  
<<< Previous 10 Messages Goto Initial 10 Messages
From: Darren New
Subject: Re: All your radix are belong to us!
Date: 1 Aug 2011 13:22:47
Message: <4e36e0e7$1@news.povray.org>
On 8/1/2011 9:30, Warp wrote:
>    Nobody claimed it is. It's just something you have to live with if you
> program in C (or its close variants).

Yes, I understand that.

>    But you *can't* expect something specific to happen if you dereference
> null (even if you do it "separately").

I know that too. I really do completely understand the problem. It's exactly 
why I'd say that maybe C or its close variants aren't good for a new user. 
I'm merely pointing out that "it isn't surprising if you already know it's 
going to happen" combined with "you should know it's going to happen because 
you need to understand the detailed rules of every single operation possible 
to write a program that silently doesn't do something good" combines to make 
"I only know a little bit" a bad choice.

> If you dereference null, *anything*
> can happen (including the following code doing something completely different
> than what you expect).

And it's not just dereferencing null. It's any of the undefined behaviors 
which can lead to the compiler doing very unintuitive things if you're not 
aware of the rule.

-- 
Darren New, San Diego CA, USA (PST)
   How come I never get only one kudo?


Post a reply to this message

From: Warp
Subject: Re: All your radix are belong to us!
Date: 1 Aug 2011 13:50:17
Message: <4e36e759@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> > If you dereference null, *anything*
> > can happen (including the following code doing something completely different
> > than what you expect).

> And it's not just dereferencing null. It's any of the undefined behaviors 
> which can lead to the compiler doing very unintuitive things if you're not 
> aware of the rule.

  OTOH "undefined behavior" also allows for the compiler to, for example,
add sanity checks and issue clear runtime errors when these kinds of errors
happen.

  Some compilers actually do this with a bunch of undefined behavior
situations when compiling in debug mode. However, it's a rather curiously
rare thing to do. I have been wondering why C/C++ compilers don't have a
"super-debug mode" where *everything* that can possibly go wrong is checked
(if it can be physically checked), completely regardless of how slow the
program becomes. A bit like a "builtin valgrind" (but which adds even more
checks which the compiler can do because it can see the source code). Only
few C/C++ compilers have anything even resembling this, and usually in a
relatively limited form (ie. the debugging mode doesn't even do all the
same checks as valgrind does).

  Maybe it's a question of complexity vs. demand, or something.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: All your radix are belong to us!
Date: 1 Aug 2011 14:53:22
Message: <4e36f622$1@news.povray.org>
On 8/1/2011 10:50, Warp wrote:
>    Maybe it's a question of complexity vs. demand, or something.

Also compatibility, I think. To check whether you're using a stray pointer, 
you'd have to store more than the pointer, which means void* might change 
size, which breaks anything precompiled you link to.

Interestingly, too, I read that Microsoft has an "Application Verifier" that 
does things like intentionally initializing stack frames to random garbage 
(rather than leaving whatever's there), and they find many people don't test 
under the "application verifier" because it breaks too much of their code. 
(For example, a lot of the "application compatibility shims" fix stuff the 
application verifier would have detected had they used it.)

There used to be lint, which would seem to address the complaint that "it 
would slow down the compiler."  I guess it's easier to just make it flags 
nowadays rather than maintain a separate program, tho.

I suspect 99% of the people writing code are writing code that doesn't get 
used in any application but their own, so they write it, test it, it seems 
to work well, they release the executable. It's a lot harder to get 
libraries like boost or openssl or whatever working on every compiler in 
every environment.

-- 
Darren New, San Diego CA, USA (PST)
   How come I never get only one kudo?


Post a reply to this message

From: Warp
Subject: Re: All your radix are belong to us!
Date: 1 Aug 2011 15:19:25
Message: <4e36fc3d@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> On 8/1/2011 10:50, Warp wrote:
> >    Maybe it's a question of complexity vs. demand, or something.

> Also compatibility, I think. To check whether you're using a stray pointer, 
> you'd have to store more than the pointer, which means void* might change 
> size, which breaks anything precompiled you link to.

  There may indeed be situations where debugging code could become
completely incompatible with a third-party precompiled library. However,
at the very least it would be nice if C/C++ compilers had a debug mode
which makes the compiler program behave like if it was run using a tool
like valgrind. Valgrind can do it even without the help of a compiler,
so there's nothing stopping the compiler itself just embedding some kind
of "valgrind" into the program itself. (And, as said, since the compiler
has the source code of the program being tested to work with, it can
probably add even more checks than what valgrind alone can.)

  Visual C++ has a decent debug mode, but I wish it did more. It would be
nice if gcc had a significantly expanded debug mode. It's not like it
would be impossible.

  On a different note, gcc and many other C/C++ compilers have a mode
which tries to profile the code as accurately as possible in terms of
how much time is spent on which parts of the code (in linux this is
used in conjunction with gprof to get the results). This can sometimes
be quite useful to find bottlenecks. I wonder if other programming
languages have similar tools.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: All your radix are belong to us!
Date: 1 Aug 2011 17:04:17
Message: <4e3714d1$1@news.povray.org>
On 8/1/2011 12:19, Warp wrote:
> so there's nothing stopping the compiler itself just embedding some kind
> of "valgrind" into the program itself.

Back when Pascal was popular, I did an enhancement to the Pascal compiler 
used at my university for teaching. Each allocation bumped a global counter 
and put the result in both the pointer and the block of allocated data. It 
also chained together all the data blocks.

Then, every time you used a pointer, it would walk the blocks of allocated 
memory to make sure the pointer was still on the list, then check that the 
counter values were the same. The former kept you from using dangling 
pointers, and the latter kept you from using a pointer that was dangling but 
happened to get reallocated later.

Obviously, performance sucked, but it was only turned on for teaching 
purposes, so that's OK.  And of course you can't do this (as easily) in a 
language that supports pointer arithmetic; you'd have to treat allocations 
as base+index.

>    Visual C++ has a decent debug mode, but I wish it did more. It would be
> nice if gcc had a significantly expanded debug mode. It's not like it
> would be impossible.

I would think anything where you say "we can rely on undefined behavior not 
happening in order to improve this", you could simply define the behavior as 
"we check for this, and drop into the debugger (or whatever) if we find it."

But to be fair, gcc and other compilers have come a long way. They warn you 
if you use variables that may be uninitialized, they warn you if you pass 
the wrong types to printf with a literal formatting argument (which is why 
the iostream argument that it's better because it's strongly typed never 
made much sense to me), and so on.

It would probably be really complicated to check even more stuff.

> I wonder if other programming languages have similar tools.

Stuff that's interpreted (or bytecoded) generally has tools like this, but 
they tell you more what's happening (i.e., "lots of iterations of this 
line") rather than the actual microseconds taken precisely, in part because 
the precision isn't as repeatable in such environments. You can usually see 
what lines were run, how much memory was allocated to particular types, and 
how long individual lines took, but I don't think they tend to go to 
exceptional effort to do better than what you'd get from the straightforward 
"read the CPU performance counter" type of thing.

-- 
Darren New, San Diego CA, USA (PST)
   How come I never get only one kudo?


Post a reply to this message

From: Warp
Subject: Re: All your radix are belong to us!
Date: 1 Aug 2011 17:50:20
Message: <4e371f9c@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> they warn you if you pass 
> the wrong types to printf with a literal formatting argument (which is why 
> the iostream argument that it's better because it's strongly typed never 
> made much sense to me)

  It depends on the compiler. Some compilers, especially the slightly older
ones, don't make such checks.

  Of course the major problem with the printf-style of I/O is that it breaks
abstraction, even in C. You just have to do something this to get a problem:

typedef int MySpecialInt;

...

void foo(MySpecialInt i)
{
    printf("The parameter was: %???\n", i);
}

  What to put as a format? Even if you put "%i" and have it work ok, it
breaks the abstraction of MySpecialInt because now you can't change it
without breaking the printf. Obviously the C++ streams have no such
problem.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: All your radix are belong to us!
Date: 1 Aug 2011 18:21:10
Message: <4e3726d6$1@news.povray.org>
On 8/1/2011 14:50, Warp wrote:
>    It depends on the compiler. Some compilers, especially the slightly older
> ones, don't make such checks.

gcc has been doing it for ages. (Since I haven't used gcc to do a printf in 
ages, and I remember doing it... :-)  But yeah, I meant more that it's 
theoretically pretty easy to cover that case.

>    Of course the major problem with the printf-style of I/O is that it breaks
> abstraction, even in C.

Yeah, I guess "breaks abstraction" is more precise than "typesafe".  More 
like "type change safe."  I remember being annoyed when there were no printf 
codes for things like size_t and diff_t and so on.

I think C# actually came up with quite a sweet compromise. (Well, maybe not 
came up with, maybe "stole", but it's pretty good anyway.)  You put in 
something like

    output.write("blah {0:x} blah {2:y} blah {1:0,000.00}", a, b, c);

that calls a.ToString("x") then c.ToString("0,000.00") then b.ToString("y") 
and inserts the results in the appropriate place. That way you don't have 
problems like cout<<hex maybe leaving the stream screwed up, and each custom 
type can configure its own meaning for formatting strings. It's typesafe and 
abstraction safe, *and* it lets you put the formatting strings in a database 
for internationalization.

Of course, C# turns each thing into a string and then outputs it, instead of 
outputting them bit by bit, but one could work the same sort of API with a 
stream interface instead of a string interface.

There's also a slightly weird thing where something different gets called 
depending on whether it's one letter after the colon, multiple letters after 
the colon, multiple colons, or something like that. I don't remember the 
details at this point.

There's also an implicit locale passed in, so you can seamlessly have 
multiple concurrent locales and have all the formatting stuff do the right 
thing, pick the right date and comma format, pick the right character 
encoding, etc. The trick is the locale goes in as another argument to 
ToString(), so you can use as many different locales as you want. I never 
really learned it well enough to understand all the combinations possible, tho.

>    What to put as a format? Even if you put "%i" and have it work ok, it
> breaks the abstraction of MySpecialInt because now you can't change it
> without breaking the printf.

Last time I had to do something like that, I used

typedef int MySpecialInt;
#define MySpecialIntFmt "%i"

and then

printf("Here are " MySpecialIntFmt " integers", i);

But yeah, that was way uglier than it needed to be, especially if you needed 
to start putting the strings in an localization file, which is the point to 
start with. :-)

-- 
Darren New, San Diego CA, USA (PST)
   How come I never get only one kudo?


Post a reply to this message

From: Lars R 
Subject: Re: All your radix are belong to us!
Date: 2 Aug 2011 04:16:37
Message: <4e37b265@news.povray.org>
On 08/01/11 17:58, Darren New wrote:
> On 8/1/2011 4:13, Lars R. wrote:
>> It is not surprising if you _know_ C.
>> i.o.w. if it is surprising for you, your C knowledge are incomplete. ^^
> 
> Sure. It's also surprising when your leg disappears, simply because
> while you know you're in a minefield, your knowledge of that minefield
> is incomplete.

ACK.

The spirit of C is: "trust the programmer" because the programmer knows
what (s)he does. If that premise is wrong, anything goes.

Ex falso sequitur quodlibet. :-D

> That doesn't mean it's a *good* thing. Yes, it can be surprising even to
> those who know C well enough to write an operating system kernel in it.

AFAIK most "kernel hackers" knows a lot about their topic, e.g. their
hardware, their data structures (file systems) and so on. But most of
them are not academic C language evangelists who can quote every
paragraph of the ISO C language standard.

> The whole "it's only surprising if you don't know it'll happen"
> tautology is silly. The problem is that composing two perfectly valid
> statements makes an invalid program that behaves completely differently
> than how you would expect from each of those two statements separately.

Crossing the street on foot is fine.
Driving on the streat by car is also fine.

But crossing the street while someone else is driving on can be
disastrous. :-)


L.


Post a reply to this message

From: Warp
Subject: Re: All your radix are belong to us!
Date: 2 Aug 2011 14:03:47
Message: <4e383c02@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> I think C# actually came up with quite a sweet compromise. (Well, maybe not 
> came up with, maybe "stole", but it's pretty good anyway.)  You put in 
> something like

>     output.write("blah {0:x} blah {2:y} blah {1:0,000.00}", a, b, c);

  In C++ you could use the boost format library, which allows you to do
things like this:

    std::cout << boost::format("writing %1%, x=%2% : %3%-th try")
                 % "toto" % 40.23 % 50;

  (OTOH I'm guessing this is less efficient than the direct approach.)

> Last time I had to do something like that, I used

> typedef int MySpecialInt;
> #define MySpecialIntFmt "%i"

> and then

> printf("Here are " MySpecialIntFmt " integers", i);

  Which is inconvenient if you need to use some format specifiers (such
as printing at least 5 digits, with leading zeros).

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: All your radix are belong to us!
Date: 2 Aug 2011 14:20:24
Message: <4e383fe8$1@news.povray.org>
On 8/2/2011 11:03, Warp wrote:
>      std::cout<<  boost::format("writing %1%, x=%2% : %3%-th try")
>                   % "toto" % 40.23 % 50;
>
>    (OTOH I'm guessing this is less efficient than the direct approach.)

I'm guessing boost::format has to return something that overloads % in the 
same way that cout overloads <<. I'm not sure from your example whether it 
supports the flexible formatting stuff either, which was more my point in 
the example.

>> printf("Here are " MySpecialIntFmt " integers", i);
>
>    Which is inconvenient if you need to use some format specifiers (such
> as printing at least 5 digits, with leading zeros).

Yeah. I never needed to, but I suppose you could use just "i" instead of 
"%i". In any case, it's clearly not flexible enough to handle things the way 
you'd like.

-- 
Darren New, San Diego CA, USA (PST)
   How come I never get only one kudo?


Post a reply to this message

<<< Previous 10 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.