POV-Ray : Newsgroups : povray.off-topic : Standard libraries Server Time
6 Sep 2024 11:19:17 EDT (-0400)
  Standard libraries (Message 79 to 88 of 108)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 00:09:21
Message: <49b35301$1@news.povray.org>
Nicolas Alvarez wrote:
> Darren New wrote:
>> I can pass you a void* and
> 
> That's a C feature. Real C++ programmers don't use void*. So no, of course
> you have no RTTI on a void*.

OK. What am I doing wrong here, that I'm not getting the size of the actual 
instance passed in?

#include <iostream>

class Alpha {
   public:
   int i;
   Alpha() { i = 9; }
   virtual ~Alpha() { }
   virtual int yidda() { return 0; }
   virtual int mysize() { return sizeof(*this); }
};

class Beta : public Alpha {
   public:
   long l0, l1, l2, l3, l4, l5, l6, l7;
   Beta() { i = 10; }
   virtual ~Beta() { }
   virtual int yidda() { return 1; }
};

void show_size(Alpha & xyz) {
   std::cout << sizeof(xyz) << std::endl;
   std::cout << xyz.mysize << std::endl;
}

int main() {
   Alpha alpha;
   Beta  beta;
   show_size(alpha);
   show_size(beta);
   return 0;
}

Why does this print "8 8 8 8"? If there's RTTI, shouldn't I at least be able 
to figure out how big my structure is without having to code a function to 
calculate it for every function?  Seriously, if you wanted to write whatever 
structure "show_size" got passed out to a file, how would you do it? Would 
you have to write a "return sizeof(*this)" in each and every class as a 
virtual function? A function inherited by the parent into the child doesn't 
know that "this" is pointing to a child type?  (I tried adding more longs to 
alpha and I started getting 32's, so it's not giving me the size of the 
reference itself.)

If I copy the text of mysize() into Beta's class, mysize() returns 40 for 
betas. That seems kind of ... not right, to me. I duplicate a virtual 
function into a child class without changing it, and it gives different 
answers than if I inherited it?

>> The traceback in your exceptions
>> can tell you what the values passed as arguments to the function on each
>> frame...
> 
> Yes they can.

I wasn't aware C++ even defined tracebacks on exceptions. How does one 
access that feature? The googles with the obvious words mostly talk about 
python exceptions passing through C++, and the g++ exception.h file declares 
exception as having a constructor, destructor, and a "what" field, but no 
traceback. What should I google on to find the right invocation to get the 
traceback out of an exception?

>> Hell, you can't even tell me how big an array is
> No, but you'll see me using std::vector, not arrays, in C++.

Yes, because you can't see how big an array is.

>> I know how it *won't* be implemented. It won't be implemented such that
>> references to local variables survive the end of the stack frame those
>> local variables are allocated in. That's enough.
> 
> They never do,

Well, no, not in C++. That's kind of my point. In other languages with 
lambdas, yes, they do. That's why it's called a closure. That's why I was 
asking stupid questions about how C++ manages to do that. :-)

> And in my mind it wouldn't be a stack if it kept
> alive after 'popped' :D

Well, yes. That's exactly why I'm asking "Wow, how does C++ do that??" 
Because, like, that's what "lambda" means, and C++ can't do it, so I'm 
trying to figure out what amazing mechanism they used.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Warp
Subject: Re: Standard libraries
Date: 8 Mar 2009 12:03:02
Message: <49b3ec36@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> OK. What am I doing wrong here, that I'm not getting the size of the actual 
> instance passed in?

[snip]

> Why does this print "8 8 8 8"? If there's RTTI, shouldn't I at least be able 
> to figure out how big my structure is without having to code a function to 
> calculate it for every function?

  The problem is that sizeof() is a static construct which is evaluated at
compile time, not something evaluated at runtime. sizeof() in particular
does *not* take into accout RTTI. When you say "sizeof(*this)" (in your
example), that's by standard specification exactly identical to
"sizeof(Alpha)".

  But C++ does have RTTI. For example try this:


#include <iostream>
#include <string>
#include <typeinfo>

class Alpha
{
 public:
    virtual ~Alpha() {}
    std::string myType() const { return typeid(*this).name(); }
};

class Beta: public Alpha
{
};

int main()
{
    Alpha obj1;
    Beta obj2;
    Alpha& obj3 = obj2;

    std::cout << obj1.myType() << " "
              << obj2.myType() << " "
              << obj3.myType() << std::endl;
}


  Even though the class Alpha does not see the class Beta in any way (you
could make completely sure of that by putting them in different compilation
units), it will still return the correct typeid name depending on whether
the object is really of type Alpha or of type Beta.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 13:29:03
Message: <49b4005f$1@news.povray.org>
Warp wrote:
> units), it will still return the correct typeid name depending on whether
> the object is really of type Alpha or of type Beta.

Does the typeid tell you anything but basically the name? It looks like 
there's just a textual name and a total (but otherwise undefined) ordering 
on types. No way to actually use the type information to do something I'd 
consider useful.  Is this the sort of thing that compilers extend, or is the 
only actual use to get the name of the type or compare types in a template?

It doesn't really look like the type information lets you do much with the 
contents of the type. It doesn't tell you anything about the type - it just 
tells you the ID of the type. It doesn't tell you how big it is, or which 
members are pointers, or anything like that that would let you do something 
like serialize the data out to a file. That's usually what I think of when I 
hear "run-time type information". Not "I can compare two values in a 
statically-typed language and see if they're the same type." :-)

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Warp
Subject: Re: Standard libraries
Date: 8 Mar 2009 15:23:29
Message: <49b41b31@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> It doesn't really look like the type information lets you do much with the 
> contents of the type. It doesn't tell you anything about the type - it just 
> tells you the ID of the type. It doesn't tell you how big it is, or which 
> members are pointers, or anything like that that would let you do something 
> like serialize the data out to a file. That's usually what I think of when I 
> hear "run-time type information". Not "I can compare two values in a 
> statically-typed language and see if they're the same type." :-)

  "Doing something depending on which type of object *this is" is precisely
what virtual functions are for, and that's the RTTI C++ has. Additionally,
you can get a unique ID for each type of object (resolvable at runtime,
as demonstrated), if you find a use for that. (One possible use could be
that objects could register themselves to some centralized, non-template
factory, using their own typeid as key, so that the factory could create
clones of those objects at runtime, based on those typeids.)

  "It doesn't tell you how big it is, or which members are pointers, or
anything like that" doesn't sound very OO to me. The whole idea of objects
is that they are abstract: You don't know what they have inside, nor do
you even need to know.

  I surely can understand why such information could sometimes be useful,
but it still sounds to me like you are accessing the internals of an object,
bypassing its public interface, which is something that breaks the basic
idea of modularity.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 16:53:45
Message: <49b43059$1@news.povray.org>
Warp wrote:
>   "Doing something depending on which type of object *this is" is precisely
> what virtual functions are for, and that's the RTTI C++ has.

OK. I guess "RTTI" and reflection aren't really as related as I thought they 
were. I find languages without metaclass-style operations are exceedingly 
tedious to work with, in the kinds of stuff I usually write. Hence my 
obvious disdain for the limited RTTI that C++ provides. However, yes, I'll 
grant you that virtual functions are indeed based on run-time type 
information. I'd just prefer a version that doesn't require me to 
reimplement in code all the stuff I already told the compiler about.

I'm kind of surprised that copying a virtual function unchanged into a child 
that inherits it changes its functionality.  That seems completely counter 
to the whole idea, to me.

>   I surely can understand why such information could sometimes be useful,
> but it still sounds to me like you are accessing the internals of an object,
> bypassing its public interface, which is something that breaks the basic
> idea of modularity.

You certainly are, when you use features like that, yes. But when the 
interface is made available to do that safely, it provides a lot of 
benefits. It's not how you want to normally interact with an object, but 
rather part of a meta-protocol for interacting with arbitrary objects. It's 
no different really than having a mix-in class, or having methods on the 
base "object" class (for single-rooted languages).

I.e., in much the same way that templates keep you from having to write the 
same code for lots of different classes, things like reflection prevent you 
from having to write the same code *inside* lots of different classes. 
There's nothing that goes on with reflection that you couldn't code manually 
as virtual functions in each class. The reflection just lets you put into a 
library some kinds of functions that would otherwise be scattered into each 
class that wants to use them. For example, with reflection, I could expose a 
class via COM (which is quite object-oriented), and do so without having to 
manually write the COM wrapper - write once, use lots. It's basically 
looking at the same information you already gave the compiler once, and it 
keeps you from having to duplicate the declarations in some second language 
(like string literals or AST structures or ...) so that you can access them.

It's pretty much exactly like sizeof() in C, which lets you invoke malloc() 
without having to do a lot of manual stuff for each particular type of 
struct you want to malloc. It's just looking at compile-time information and 
packaging it up in a way that lets you examine it. It would be kind of silly 
in C to say "you have to manually count up how many bytes you use and store 
that somewhere if you want to allocate a structure on the heap", when you've 
already told the compiler what's in the structure.

Of course, there would be some runtime overhead involved, like storing a 
description of the class (as an AST perhaps) in the executable file.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 17:38:03
Message: <49b43abb@news.povray.org>
Darren New wrote:
> Well.... I think it's one of the few languages where you can't tell
> whether something's invoking a function or adding a name to the namespace
> at compile
> time.  It would seem to make writing parsers and such harder than it needs
> to be.
> 
> I'll grant that there are a number of languages where (say) writing "F(5)"
> doesn't tell you whether F is a function, a pointer to a function, or a
> function that returns another function, say.

In Python, f(5) could be a normal function call if f is a function, a method
call if f is a bound method object, a method call if f is an instance of a
class with a __call__ method, or an object instantiation (passing 5 to the
__init__ method) if f is a class name.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 17:40:58
Message: <49b43b6a@news.povray.org>
Darren New wrote:
> Nicolas Alvarez wrote:
>> Darren New wrote:
>>> The traceback in your exceptions
>>> can tell you what the values passed as arguments to the function on each
>>> frame...
>> 
>> Yes they can.
> 
> I wasn't aware C++ even defined tracebacks on exceptions.

It doesn't.

> How does one access that feature?

Through your debugger :)


Post a reply to this message

From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 17:49:25
Message: <49b43d65$1@news.povray.org>
Nicolas Alvarez wrote:
> Darren New wrote:
>> Well.... I think it's one of the few languages where you can't tell
>> whether something's invoking a function or adding a name to the namespace
>> at compile
>> time.  It would seem to make writing parsers and such harder than it needs
>> to be.
>>
>> I'll grant that there are a number of languages where (say) writing "F(5)"
>> doesn't tell you whether F is a function, a pointer to a function, or a
>> function that returns another function, say.
> 
> In Python, f(5) could be a normal function call if f is a function, a method
> call if f is a bound method object, a method call if f is an instance of a
> class with a __call__ method, or an object instantiation (passing 5 to the
> __init__ method) if f is a class name.

That's the language I was thinking of, primarily, yes. :-) But in all those 
cases, it's a call. It's not changing the structure of the program.

In C++, you can write
   alpha beta(gamma);
and not know whether that's a declaration or executable code. Most languages 
you can tell what's a declaration and what's executable code without reading 
all previous declarations.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 17:53:15
Message: <49b43e4b$1@news.povray.org>
Nicolas Alvarez wrote:
> Darren New wrote:
>> Nicolas Alvarez wrote:
>>> Darren New wrote:
>>>> The traceback in your exceptions
>>>> can tell you what the values passed as arguments to the function on each
>>>> frame...
>>> Yes they can.
>> I wasn't aware C++ even defined tracebacks on exceptions.
> 
> It doesn't.

Then the traceback in your exceptions can't tell you the values, can it?

>> How does one access that feature?
> Through your debugger :)

I don't really want to tell my customers to run my production code under a 
debugger and copy/paste the traceback into the logfile before sending it to me.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 17:57:59
Message: <49b43f67@news.povray.org>
Darren New wrote:
> In C++, you can write
>    alpha beta(gamma);
> and not know whether that's a declaration or executable code. Most
> languages you can tell what's a declaration and what's executable code
> without reading all previous declarations.

You're calling alpha constructor. I don't see how that's different from
Python class creation syntax, calling __init__.


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

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