|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Darren New wrote:
> Nicolas Alvarez wrote:
>> Darren New wrote:
>>> 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?
Exceptions have no "traceback" directly visible at runtime from inside the
code. You can use platform-specific code in an exception handler to get a
stack trace (by following stack pointers).
>>> 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.
KDE has a crash handler similar to Windows's, except it can't automatically
send the report back to the developer. It gives you a stacktrace, including
all the function parameters, and lets you save the file to upload to the
bug tracker.
When an application crashes, the crash handler *attaches* a debugger to the
just-segfaulted app, loads the debugging symbols from a different file,
gets a stacktrace, and lets the crashed app die and R.I.P.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Nicolas Alvarez wrote:
> Darren New wrote:
>> In C++, you can write
>> alpha beta(gamma);
> You're calling alpha constructor.
How do you know you're not declaring a function beta that take an argument
of type gamma and returns an alpha?
--
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
|
|
| |
| |
|
|
|
|
| |
|
|