Most everybody knows that class member receive the this pointer as the first "invisible" parameter of the function.
Is this specified in C++ standard? Can a certain compiler implementation pass it in a different way? Dedicated registry for example.
That's certainly how the very first versions of C++ were implemented (early C++ was transformed into C code), but be assured that the C++ standard does not mandate this.
Passing it as the last parameter value also seems feasible, and for virtual functions, some different technique altogether.
Related
For my C++ DLLs, I am using the factory pattern with abstract interfaces.
In the disadvantages section of this article, it says:
An abstract interface method cannot return or accept a regular C++ object as a parameter. It has be either a built-in type (like int, double, char*, etc.) or another abstract interface. It is the same limitation as for COM interfaces.
Could you elaborate what this means? What exactly can I not do and why?
Is there any further reading available on this matter?
This statement does not look accurate. Abstract interface method can return or accept C++ class instance (or its pointer) as parameter. There is no COM-like limitation here. It might be unsafe though in case caller/callee are built using different compiler settings, alignments, using different allocators etc. in which case the same C++ class is defined slightly differently and the mismatch might result in unexpected behavior. That is, it is not about "cannot", it is about it might lead to unobvious problems.
A frequent example of the problem in question is passing CString as a parameter:
function in dll doesn't receive CString argument value
There are different parameter passing techniques like - Call By Value, Call By Reference, Call By Value Result, Call By Name, Call By Text and Call By Need in Programming Languages.
I have seen implementations of Call By Value and Call By Reference in C/C++; but the other techniques were taught only with simple plain examples, where we are given that this example uses say "Call By Value Result" and so answer accordingly. I was wondering whether the other techniques have ever been implemented in C/C++ or any other languages or were they just theoretical?
C provided and still provides pass by value only.
In C++ it's only by value or by reference. The other techniques can be simulated using existing C++ language constructs - specially crafted conversion operators and constructors.
Check this the diff usage of parameters passing technique
http://c2.com/cgi/wiki?ParameterPassing
In Visual Studio 2013 a new calling convention _vectorcall exists. It is intended for usage with SSE data types that can be passed in SSE registers.
You can specify the calling convention of a member functions like so.
struct Vector{//a 16 byte aligned type
_m128i _vectorcall operator *(Vector a);
};
This works, it compiles, and the type can be passed by value despite having 16 alignment requirements.
On the other hand if I try to attach it to any constructors (which seems perfectly logical), it fails.
struct Vector
_vectorcall Vector(SomeOtherTypeWith16Alignment a);
};
The compiler spits out the warning message (I have warnings as errors):
warning C4166: illegal calling convention for constructor/destructor.
Forcing me to change the code to this:
struct Vector{
Vector(SomeOtherTypeWith16Alignment a); //fails to compile
};
Which also fails to compile because now SomeOtherTypeWith16Alignment can't be passed by value since _vectorcall isn't enabled on the constructor.
So I am forced to change it to this.
struct Vector{
Vector(const SomeOtherTypeWith16Alignment& a);
};
Which compiles. But it is no longer using _vectorcall and likely won't pass the data in SSE registers as I'd prefer...
So basically, why the hell can't I specify the calling convention used by constructors?
This may be Visual C++ specific (_vectorcall certainly is). I have not tried this on other compilers--
This is not so much an answer, but more of a collection of observations about this situation. This is indeed an intriguing question because there really seems to be something (I don't know what) that makes constructors (and destructors) fundamentally incompatible with calling conventions.
First of all, don't look for an answer in the C++ standard, because the standard does not care about calling conventions, in fact, the only mention of it in the standard is as an example of something that is out of the scope of that document (i.e., "implementation-defined"). So, the standard does not "forbid" the possibility of specifying or using different calling conventions for the constructors (or destructor).
From a little research and testing, it appears that the situation is as follows for the different main compilers (as best I could gather):
MSVC allows you to specify a calling convention, but ignores it (with a warning) for anything other than "stdcall", which it considers as meaning "thiscall" (stdcall-style thiscall), which is already the default anyways. Changing the default calling convention via a command-line option (/Gz for instance) does not affect non-static member functions such as constructors. In other words, there is no way to change the calling convention on constructors, whatever you try to specify, it will be ignored.
Both ICC and GCC ignore (with a warning) any attempt to specify a calling convention on the constructor.
Clang ignores (with a warning) any attempt to specify a calling convention on the constructor, unless it is "cdecl", which also the default (cdecl-style thiscall).
In other words, all compilers seem to be very stubborn about no allowing any other kind of calling convention on the constructors besides the default one. And the core question is: Why?
Here are a few thoughts on that (speculations).
First off, traditionally, calling conventions have been more about binary compatibility than about performance optimization, i.e., you specify calling conventions when linking with and calling functions from different languages or compilers (e.g., traditionally between C, C++, Pascal and Fortran). And so, this could explain why certain C++ features are excluded from that. For instance, if you are creating an interface for a C++ library (maybe calling it from a different language), then you either have to fall-back on a C API, meaning no classes, no constructors and no member functions, or you have to expose a C++ API on a platform with a standard ABI (e.g, Itanium) which fixes the calling convention. That makes specifying a calling convention for constructors completely useless from a binary compatibility point of view. That may explain why this has been "ignored" (not implemented by the compilers) as a low priority feature.
Another issue that might be involved here, for the constructors specifically, is that if you look for example at the Itanium ABI specification you can see that constructor calls are quite special. In particular, virtual inheritance requires a temporary virtual table pointer to be passed along. This may explain why it is quite a bit more difficult for compiler implementers to provide a variant of each possible calling convention for constructors. In other words, it's not as simple as just adding a "this" pointer as the first "hidden" argument and then applying a standard C calling convention (as it does with normal non-static member functions). I don't think that it would be impossible to implement those alternative calling conventions for constructors, but it would be extra trouble that compiler-vendors simply have not got around to implementing (yet). Also, given the calls to base class constructors, it may also create problems with diagnostics (verifying that base-class constructor calling conventions are compatible with the derived-class calling convention). So, this might simply be a case of "too much trouble; didn't do it". And the fact that the standard allows it, but none of the compilers do it is a strong indicator that this may be the case.
Beyond that, I cannot offer any definitive answer as to why this would be somehow impossible to achieve. The only way you could get a definitive answer is if you find a person who is directly involved in implementing one of those compilers and who has looked into trying to support different calling conventions on constructors. And note that it's possible that such a person doesn't even exist (your best bet might be to check with the LLVM/Clang developer community to see if anyone has looked into this problem).
Why are those C++11 new functions of header <string> (stod, stof, stoull) not member functions of the string class ?
Isn't more C++ compliant to write mystring.stod(...) rather than stod(mystring,...)?
It is a surprise to many, but C++ is not an Object-Oriented language (unlike Java or C#).
C++ is a multi-paradigm language, and therefore tries to use the best tool for the job whenever possible. In this instance, a free-function is the right tool.
Guideline: Prefer non-member non-friend functions to member functions (from Efficient C++, Item 23)
Reason: a member function or friend function has access to the class internals whereas a non-member non-friend function does not; therefore using a non-member non-friend function increases encapsulation.
Exception: when a member function or friend function provides a significant advantage (such as performance), then it is worth considering despite the extra coupling. For example even though std::find works really well, associative containers such as std::set provide a member-function std::set::find which works in O(log N) instead of O(N).
The fundamental reason is that they don't belong there. They
don't really have anything to do with strings. Stop and think
about it. User defined types should follow the same rules as
built-in types, so every time you defined a new user type,
you'd have to add a function to std::string. This would
actually be possible in C++: if std::string had a member
function template to, without a generic implementation, you
could add a specialization for each type, and call
str.to<double>() or str.to<MyType>(). But is this really
what you want. It doesn't seem like a clean solution to me,
having everyone writing a new class having to add
a specialization to std::string. Putting these sort of things
in the string class bastardizes it, and is really the opposite
of what OO tries to achieve.
If you were to insist on pure OO, they would have to be
members of double, int, etc. (A constructor, really. This
is what Python does, for example.) C++ doesn't insist on pure
OO, and doesn't allow basic types like double and int to
have members or special constructors. So free functions are
both an acceptable solution, and the only clean solution
possible in the context of the language.
FWIW: conversions to/from textual representation is always
a delicate problem: if I do it in the target type, then I've
introduced a dependency on the various sources and sinks of text
in the target type---and these can vary in time. If I do it in
the source or sink type, I make them dependent on the the type
being converted, which is even worse. The C++ solution is to
define a protocol (in std::streambuf), where the user writes
a new free function (operator<< and operator>>) to handle
the conversions, and counts on operator overload resolution to
find the correct function. The advantage of the free function
solution is that the conversions are part of neither the data
type (which thus doesn't have to know of sources and sinks) nor
the source or sink type (which thus doesn't have to know about
user defined data types). It seems like the best solution to
me. And functions like stod are just convenience functions,
which make one particularly frequent use easier to write.
Actually they are some utility functions and they don't need to be inside the main class. Similar utility functions such as atoi, atof are defined (but for char*) inside stdlib.h and they too are standalone functions.
I was looking through the plans for C++0x and came upon std::initializer_list for implementing initializer lists in user classes. This class could not be implemented in C++
without using itself, or else using some "compiler magic". If it could, it wouldn't be needed since whatever technique you used to implement initializer_list could be used to implement initializer lists in your own class.
What other classes require some form of "compiler magic" to work? Which classes are in the Standard Library that could not be implemented by a third-party library?
Edit: Maybe instead of implemented, I should say instantiated. It's more the fact that this class is so directly linked with a language feature (you can't use initializer lists without initializer_list).
A comparison with C# might clear up what I'm wondering about: IEnumerable and IDisposable are actually hard-coded into language features. I had always assumed C++ was free of this, since Stroustrup tried to make everything implementable in libraries. So, are there any other classes / types that are inextricably bound to a language feature.
std::type_info is a simple class, although populating it requires typeinfo: a compiler construct.
Likewise, exceptions are normal objects, but throwing exceptions requires compiler magic (where are the exceptions allocated?).
The question, to me, is "how close can we get to std::initializer_lists without compiler magic?"
Looking at wikipedia, std::initializer_list<typename T> can be initialized by something that looks a lot like an array literal. Let's try giving our std::initializer_list<typename T> a conversion constructor that takes an array (i.e., a constructor that takes a single argument of T[]):
namespace std {
template<typename T> class initializer_list {
T internal_array[];
public:
initializer_list(T other_array[]) : internal_array(other_array) { };
// ... other methods needed to actually access internal_array
}
}
Likewise, a class that uses a std::initializer_list does so by declaring a constructor that takes a single std::initializer_list argument -- a.k.a. a conversion constructor:
struct my_class {
...
my_class(std::initializer_list<int>) ...
}
So the line:
my_class m = {1, 2, 3};
Causes the compiler to think: "I need to call a constructor for my_class; my_class has a constructor that takes a std::initializer_list<int>; I have an int[] literal; I can convert an int[] to a std::initializer_list<int>; and I can pass that to the my_class constructor" (please read to the end of the answer before telling me that C++ doesn't allow two implicit user-defined conversions to be chained).
So how close is this? First, I'm missing a few features/restrictions of initializer lists. One thing I don't enforce is that initializer lists can only be constructed with array literals, while my initializer_list would also accept an already-created array:
int arry[] = {1, 2, 3};
my_class = arry;
Additionally, I didn't bother messing with rvalue references.
Finally, this class only works as the new standard says it should if the compiler implicitly chains two user-defined conversions together. This is specifically prohibited under normal cases, so the example still needs compiler magic. But I would argue that (1) the class itself is a normal class, and (2) the magic involved (enforcing the "array literal" initialization syntax and allowing two user-defined conversions to be implicitly chained) is less than it seems at first glance.
The only other one I could think of was the type_info class returned by typeid. As far as I can tell, VC++ implements this by instantiating all the needed type_info classes statically at compile time, and then simply casting a pointer at runtime based on values in the vtable. These are things that could be done using C code, but not in a standard-conforming or portable way.
All classes in the standard library, by definition, must be implemented in C++. Some of them hide some obscure language/compiler constructs, but still are just wrappers around that complexity, not language features.
Anything that the runtime "hooks into" at defined points is likely not to be implementable as a portable library in the hypothetical language "C++, excluding that thing".
So for instance I think atexit() in <cstdlib> can't be implemented purely as a library, since there is no other way in C++ to ensure it is called at the right time in the termination sequence, that is before any global destructor.
Of course, you could argue that C features "don't count" for this question. In which case std::unexpected may be a better example, for exactly the same reason. If it didn't exist, there would be no way to implement it without tinkering with the exception code emitted by the compiler.
[Edit: I just noticed the questioner actually asked what classes can't be implemented, not what parts of the standard library can't be implemented. So actually these examples don't strictly answer the question.]
C++ allows compilers to define otherwise undefined behavior. This makes it possible to implement the Standard Library in non-standard C++. For instance, "onebyone" wonders about atexit(). The library writers can assume things about the compiler that makes their non-portable C++ work OK for their compiler.
MSalter points out printf/cout/stdout in a comment. You could implement any one of them in terms of the one of the others (I think), but you can't implement the whole set of them together without OS calls or compiler magic, because:
These are all the ways of accessing the process's standard output stream. You have to stuff the bytes somewhere, and that's implementation-specific in the absence of these things. Unless I've forgotten another way of accessing it, but the point is you can't implement standard output other than through implementation-specific "magic".
They have "magic" behaviour in the runtime, which I think could not be perfectly imitated by a pure library. For example, you couldn't just use static initialization to construct cout, because the order of static initialization between compilation units is not defined, so there would be no guarantee that it would exist in time to be used by other static initializers. stdout is perhaps easier, since it's just fd 1, so any apparatus supporting it can be created by the calls it's passed into when they see it.
I think you're pretty safe on this score. C++ mostly serves as a thick layer of abstraction around C. Since C++ is also a superset of C itself, the core language primitives are almost always implemented sans-classes (in a C-style). In other words, you're not going to find many situations like Java's Object which is a class which has special meaning hard-coded into the compiler.
Again from C++0x, I think that threads would not be implementable as a portable library in the hypothetical language "C++0x, with all the standard libraries except threads".
[Edit: just to clarify, there seems to be some disagreement as to what it would mean to "implement threads". What I understand it to mean in the context of this question is:
1) Implement the C++0x threading specification (whatever that turns out to be). Note C++0x, which is what I and the questioner are both talking about. Not any other threading specification, such as POSIX.
2) without "compiler magic". This means not adding anything to the compiler to help your implementation work, and not relying on any non-standard implementation details (such as a particular stack layout, or a means of switching stacks, or non-portable system calls to set a timed interrupt) to produce a thread library that works only on a particular C++ implementation. In other words: pure, portable C++. You can use signals and setjmp/longjmp, since they are portable, but my impression is that's not enough.
3) Assume a C++0x compiler, except that it's missing all parts of the C++0x threading specification. If all it's missing is some data structure (that stores an exit value and a synchronisation primitive used by join() or equivalent), but the compiler magic to implement threads is present, then obviously that data structure could be added as a third-party portable component. But that's kind of a dull answer, when the question was about which C++0x standard library classes require compiler magic to support them. IMO.]