0

This quesiton is composed of a couple parts, the first has to do with the -> operator in a class. Does it take some sort of input (according to the C++ standard)? For example

some_return_type? operator->( long address ) {
    cast the address to some sort of pointer and do something with it...
    return something?...possibly... maybe not?;
}

So in reality A::SomeMethod() would refer to an address for a function in memory passed to ->. Or A::someStaticOrNonStaticDataMember would refer to an address for a field?

If so (given that we do not have access to the actual type of the class), or something like this exists, what is it, and can we reconstruct part of a pointer, or align a pointer, (or write a class with an algorithm to do this), for a class based on some information about that class, so that it had an operable -> operator, so one could write:

somePointer->A::SomeMethod();

and have it call A::SomeMethod()? And maybe make context for the memory used in the class?

  • http://stackoverflow.com/questions/4421706/operator-overloading – Creris Oct 20 '14 at 17:44
  • @Creris I am asking about `->` as generated by compilers and its behavior according to the standard, not overloading it, possibly accessing it. – The Floating Brain Oct 20 '14 at 17:45
  • I dont really understand what you want. You want to just call some universal -> operator with some address and then call some method on that? – Creris Oct 20 '14 at 17:46
  • You can´t replace "what the compiler does with `->` and `.`" with "C++ function". Period. It´s not only a convenience thing to have a `.` – deviantfan Oct 20 '14 at 17:48
  • And maybe you want to learn Asm and x86/x64 calling conventions. Something like the seocnd part of your question *ìs* possible, but again not in platform-independent and compiler-independent C++ – deviantfan Oct 20 '14 at 17:49
  • @deviantfan Im not saying we can, what I am asking is does the -> operator take input, can it be accessed in a standard way in a given chunk of memory, and can we do operations on it. – The Floating Brain Oct 20 '14 at 17:50
  • @TheFloatingBrain: Again, stop thinking that `->` is a function with parameters. It is not. `->` does nothing during runtime, it´s only to let the compiler calculate some offsets (well '.' is. '->' is just a combination of '*' and '.') – deviantfan Oct 20 '14 at 17:51
  • `reinterpret_cast(myVariableOfDifferentType)->MyMethod` – Creris Oct 20 '14 at 17:52
  • @Creris Thank you, but if we only had information on `MyType` but not `MyType` itself, are there standard attributes of `->` so we could find that operator in memory, and access it, and is there a standard input that it takes? – The Floating Brain Oct 20 '14 at 17:55
  • as mentioned before. -> is not really callable operator unless you overload it, it does nothing but say that you want to dereference your object, so that you can access member variables and functions alike of that given type. There are no attributes for ->, the way it works: on left side, you have object of some known type you want to dereference, on right side you have member variable or function found within that type's definition that you want to access. Nothing more – Creris Oct 20 '14 at 17:57
  • @deviantfan Sorry I did not respond, on your second comment, what I am asking is if there is a standard input that `->` takes, and are there standard attributes of `->` so that it can be located in memory via some algorithm? Or does the possibility exist that we could use theoretical input for `->` to locate that data in question in memory, or if there are standard attributes of this memory within a class that can allow it to be located? – The Floating Brain Oct 20 '14 at 17:58
  • @TheFloatingBrain: How many times i have to repeat it? In your compiled program and it´s memory, `->` does not exist. – deviantfan Oct 20 '14 at 17:58
  • @Creris I know `->` is really short for `(*).` I am mostly using it to summarize. What input format is the variable on the right (memory address, some thing else, etc.) and is it defined by the standard? – The Floating Brain Oct 20 '14 at 18:01
  • it must be variable or function defined inside the class you are dereferencing afaik – Creris Oct 20 '14 at 18:02
  • @Creris The pointer does not know what the passed variable or method is, what I am trying to figure out is what could be equated to the name passed? For example `A::someMethod` could be a memory address to a function in memory, then the `->` operator takes that function, runs an algorithm to align the memory inside the class to the addresses specified in the function for data members, and runs the function. – The Floating Brain Oct 20 '14 at 18:06
  • why you insist on doing it inside ->. Just call function, as mentioned, there is no way you will make -> behave as you want, unless we all misunderstood you – Creris Oct 20 '14 at 18:07
  • @deviantfan If `->` or `(*).` (`.`) do not exist as functions, does the compiler have a standard form of data, or standard attributes of the data "passed" to `->` in other words in: `somePtr->someMethod` does `someMethod` (after parsing) have to be an address in memory to a function for example? – The Floating Brain Oct 20 '14 at 18:07
  • @TheFloatingBrain: a) You should really lern Asm (really learn, not just enough to write two small programs), then you will understand what you´re asking. b) No memory is "aligned by some algorithm" to call a function. – deviantfan Oct 20 '14 at 18:09
  • also I will add, the pointer doesnt know what it has, because the pointer knows nothing to be honest. The compiler is responsible to know what the pointer can reference. And there are only really 2 things you can reference: functions and variables – Creris Oct 20 '14 at 18:09
  • @deviantfan I actually do know x86 assembly (at least some basic x86 assembly), but I am trying to work in the context of standard C++. B: I did not say it had to be, I was just giving an example of what a standard input could mean. What I am asking is, when parsing something like `soemPtr->someMethod` does `someMethod` (according to the standard, after parsing) have to be a specific type of data (an address, a chunk of memory, something else, etc.)? – The Floating Brain Oct 20 '14 at 18:12
  • @TheFloatingBrain: I´m pretty sure the standard is saying nothing about this topic (which would be "what is the compiler doing with my code") – deviantfan Oct 20 '14 at 18:14
  • @Creris Precisely, what I am trying to do is play with either how the compiler handles the pointer, or the operators applied to the pointer, or the alignment of the pointer, to point to what amounts to the '.' operator in memory so I could have a `void*` pointer for example, but with some tinkering do something like (or the equivalent of) `p->A::SomeMethod()`. – The Floating Brain Oct 20 '14 at 18:14
  • you cant. There is no void::operator->, you will have to typecast p into A via reinterpret_cast to make it instance of A, and then dereference it and call SomeMethod. Compiler is the policeman in here, not user. Compiler should follow standard, but you have to follow compiler's rules. I dont know why you want to do this. You know that the type you want to call is A, so what is the problem of static/reinterpret casting it? – Creris Oct 20 '14 at 18:16
  • @TheFloatingBrain: As said somewhere before this is possible, but not platform-independent, therefore no clean C++. C++ offers you something which will be processed by the compiler to something runnable, without the need to know anything how your CPU etc. works. If you want something else => Asm. And again, reading about calling conventions will help. – deviantfan Oct 20 '14 at 18:17
  • ...because what you´re trying to do is the thing the compiler normally will do for you. After the compiler processed your code, there is nothing left of C++. If you want to access things there, you´ll have to know your way around in the compiler output. (And C++ just does not offer such a thing itself, therefore you can´t ask the compiler to help you) – deviantfan Oct 20 '14 at 18:23
  • @deviantfan So there is nothing you know of in the standard that dictates what the compiler has to parse `SomeMethod` as in `p->SomeMethod`, and no way to "call" or reference the code the compiler compiles `->` to? (In a way this question is really about the standard). – The Floating Brain Oct 20 '14 at 18:26
  • you can take address of that function, but it will still be `return_type(type_name::*)(args)`, so still type dependant – Creris Oct 20 '14 at 18:27
  • @TheFloatingBrain Exactly. C++ does not specify how the compiled binary should look like, and the language doesn´t offer commands to access arbitrary program parts in the compiled state – deviantfan Oct 20 '14 at 18:27
  • @Creris The reason is I am trying to build something like a C.O.M, and I don't want to wrap over everything, I thought it would be more elegant, and efficient, if I could reference the data members in an object directly (and based on some meta data, reconstruct input to do so). – The Floating Brain Oct 20 '14 at 18:28
  • @deviantfan Yes, however what I am asking about is what the standard has to say about parsing algorithm. Not after the program has already been compiled to something else. – The Floating Brain Oct 20 '14 at 18:29
  • My bets are on `Implementation defined` answer – Creris Oct 20 '14 at 18:30
  • 1
    Mine too :) And what will it help if you know how the compiler handles characters of a text file? Maybe you should call it a day, this topic is circling. – deviantfan Oct 20 '14 at 18:33
  • @deviantfan I think so too. It would help if I knew what the standard says about its parsing algorithm or how it handles charterers of a text file. I am just not sure where to find that sort of thing, and the standard is a bit confusing so I thought I would ask and see others knew the answer to my question. – The Floating Brain Oct 20 '14 at 18:36
  • As Creris and me said several times, the standard doesn´t specify anthing how a compiler works; not even that a compiler is necessary (there is at least one C++ interpreter (a bad one)) – deviantfan Oct 20 '14 at 18:38
  • @deviantfan I thought the standard dictated parts of the process or described some of the steps, which is part of why C++ has to be parsed 7 times. – The Floating Brain Oct 20 '14 at 18:40
  • where you got that "C++ has to be parsed 7 times"? – Creris Oct 20 '14 at 18:42
  • @TheFloatingBrain: Where did you read the "7 times"? Nonsense. Not being an GCC expert, but it would be strange if the actual cpp-file is used more than once during one compilation process. Similar for Clang, VS... – deviantfan Oct 20 '14 at 18:42
  • @deviantfan I think I may have gotten it when I was looking up some information on the cpp grand-master certification course. I never took it, but doing some background research, I (think) remember reading that the C++ standard said that the code had to be parsed 7 times for various reasons, (each one doing something else, for example, one does preprocessing), and to ensure the code was error free, and that is part of why C++ compilers in particular are slow. :-/ Twas' a while ago. – The Floating Brain Oct 20 '14 at 18:45
  • @TheFloatingBrain: "C++ grand-master"? I would be careful with such names ... i´m looking it up now (and the preprocessor is a separate thing, but it should work with a single cycle too) – deviantfan Oct 20 '14 at 18:48
  • that is not true. Like 80% of compilation time is actual optimizing. I could write program that would read C++ file in few milliseconds too, and Im no parsing expert. I think standard doesnt even specify how you should do pre-preprocessing(the string replacements, the thing Visual doesnt bother to do) vs processing, so very theoretically speaking you could go with single pass, but most likely compilers do 2 passes over your file, first pass to do preprocessor definitions – Creris Oct 20 '14 at 18:48
  • @deviantfan & Creris This course: http://www.cppgm.org/ , twas' in a lot of media when it came out. I don't know if I got if from there, but I'm looking it up too XD – The Floating Brain Oct 20 '14 at 18:49
  • 1
    nice and all, but there is absolutly nothing from standard that says how Compilers should work. The closest rules to what compilers should do is specifying which characters are valid names of variables. The whole process of compilation is `implementation defined`, and as mentioned by @deviantfan there is at least one interpreter also. – Creris Oct 20 '14 at 18:52
  • If you guys want to post answers stating that there is no function in memory for `->`, and `(*).` that `->` is done by the compiler, and no accessible code exists for it, and there is no standard to how that is processed, I will up - vote it and mark it as an answer. – The Floating Brain Oct 20 '14 at 18:57
  • If @Creris wants, please. Got something else to do right now. – deviantfan Oct 20 '14 at 19:04
  • @Creris Why do debug builds not take 20% the time of a release build if 80% of time is optimizing? – Neil Kirk Oct 20 '14 at 19:39
  • 1
    `long` is not suitable to store a pointer address. – Neil Kirk Oct 20 '14 at 19:39
  • 1
    @NeilKirk well I just spitted some numbers :D I am no compiler engeneer, but I think I can safely say compiler will take more time on optimizations than on parsing the files in either debug or release mode. Correct me if I am wrong(I was trying to prove point, not to be exact before) – Creris Oct 20 '14 at 19:41
  • @NeilKirk Actually I have been wondering about which datatype could store a pointer address, it did not seem as though even the max of a `long long` could do it beacause it would be that there are more addresses than numbers, do you reccomend a type for ths? Also my guess would be preliminary, high level optimization, things like flipping loops around. – The Floating Brain Oct 21 '14 at 17:48
  • @TheFloatingBrain http://stackoverflow.com/questions/1845482/what-is-uintptr-t-data-type – Neil Kirk Oct 21 '14 at 18:30
  • @NeilKirk Thank you, wouldent that run out of addresses? – The Floating Brain Oct 21 '14 at 19:46
  • Any pointer can be stored in `uintptr_t` without loss of data. – Neil Kirk Oct 21 '14 at 19:55
  • @NeilKirk but doesent the possibilityveasily exiat that there are more memory addresses than possible integers in an `unsigned int`? – The Floating Brain Oct 21 '14 at 20:52
  • `uintptr_t` is not the same as `unsigned int` – Neil Kirk Oct 22 '14 at 08:07
  • @NeilKirk It says here that the longest value it can hold is the maximum value for an `unsigned int` http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/convert-10/index.html – The Floating Brain Oct 22 '14 at 17:34
  • I can't see that in the link you posted. – Neil Kirk Oct 22 '14 at 18:47
  • @NeilKirk exerpt "uintptr_t and Other Helpful Types: Other useful types provided by include signed and unsigned integer types large enough to hold a pointer. These are given as intptr_t and uintptr_t. In addition, intmax_t and uintmax_t are defined to be the longest (in bits) signed and unsigned integer types available." – The Floating Brain Oct 22 '14 at 20:21
  • Where does that say the maximum value is `unsigned int`? I really don't get where this is going. – Neil Kirk Oct 22 '14 at 21:28
  • @NeilKirk It says `intmax_t` and `uintmax_t` are the longest (in bats) signed and unsigned integer types available. However these have a limit, for the sake of the example, lets say its 10, if there are 100 memory addresses, there is no way a `uintptr_t` for example could hold pointer values for all the memory, weather it is less than or equal to the size of those data - types. – The Floating Brain Oct 22 '14 at 22:01
  • If a compiler doesn't provide a `uintptr_t` type which is large enough to hold any pointer, then it is non-standard conforming. Pointers are addresses which are numbers at the end of a day, so there is no reason a compiler cannot support an integer the same size as the pointer type. – Neil Kirk Oct 22 '14 at 22:08
  • @NeilKirk That is what I am asking, if the max integer does not meet the maximum amount of addresses then `uintptr_t` can not hold all the possible addresses in memory, right? – The Floating Brain Oct 22 '14 at 22:20
  • @TheFloatingBrain No, but that is not allowed by a conforming implementation. You can invent your own compiler to implement some C++-like language, but if it doesn't meet these requirements, it's not a C++ compiler. – Neil Kirk Oct 23 '14 at 00:04
  • @NeilKirl does every C++ program has a limited amount of memory it can use? If so, Is this implemented technologically on most platforms, including low level ones ( hypothetically stating that they have an infinite amount of addresses in memory)? – The Floating Brain Oct 25 '14 at 02:12

3 Answers3

2

From the comments it seems you want to control how Compiler handles and generates -> tokens. This is for your bad luck not possible, because Compiler doesn't expose such information, nor is it required by Standard to do so

Creris
  • 1,128
  • 9
  • 20
1

The arrow operator (->) is a dereference operator that is used exclusively with pointers to objects that have members.
foo->bar() is the same as (*foo).bar()

If you want to overload -> you should also overload *

Laura Maftei
  • 1,863
  • 1
  • 15
  • 25
  • Thank you for your answer. Yes, I do know a that, but if we did not know the type of the class, but we had some information on what it contained (lets say for now it only uses primitive types), if we had some sort of input for -> or (*). (if such an input exists), what would such input be? And Could we access -> in a standard way given standard information on it. – The Floating Brain Oct 20 '14 at 17:52
1

It is like you are trying to have "dynamic" (the C# type) but in C++, unluckily this is not possible. What could be similiar is wrapping some sort of "Closure collection" addressed by strings (a sort of scripting language) but that would be really heavy and not very nice.

Actually doing what you want with the syntax you showed is not possible.

If the type of an object is not known, then you have that object hided behind a "void *". That means basically that the only way you can use that object is by casting it back to its original type.

Suppose you have a DLL that expose 2 functions (with header files)

// creates an object of given type or null_ptr if no object match
void* getObject(std::string obj_type);

// call a method on that object
void callMethod(void* obj, std::string method_name, void* args, void* returnval);

Actually that solution (even if ugly) allows to call methods on objects that you don't know (it could be a lot better than that.) But that force you to use void* and strings. That's because how C++ resolve method names (in reality also in C# the "dynamic" type generates behind the scenes reflection code that use strings with method names and is particulary slow)

So something similiar can be achieved with

float fuelLiters = 3.0f;
void * myObj = createObject("SomeCar");
callMethod(myObj,"loadFuel", &fuelLiters, null_ptr);

you probably can make the syntax a little better with templates or some macro, but you'll never be able to do something like

myObj->A::loadFuel(fuelLiters);

What you can do is having the externally loaded class, use the same interfaces of your application, says:

class ICar{
    public:

    void loadFuel(float liters)=0;
};

In that case you can use a function that cast the opaque object handle to ICar. This is what I already doing in a library I wrote 2 years ago:

So you just need the DLL expose a method for casting the class (downcast)

//if given object is implementing a ICar, the correct pointer is returned, else
// this function will return nullptr (or throw exception if you like more)
void * downcast( typeof(ICar), myObj);

You'll need simply

ICar *myCar = static_cast<ICar>(downcast( typeof(ICar), myObj));
myCar->loadFuel(3.0f);

However note that both the DLL and your application should "know" about what "ICar" is, so they must include the "ICar" header.

doing that is definitely possible, I did it already in 2 different ways, so If you need more details about implementation I'll be happy to show a possible way (given I understood correctly your question).

CoffeDeveloper
  • 7,961
  • 3
  • 35
  • 69