Found here: https://github.com/tpaviot/oce/blob/master/src/BRepAdaptor/BRepAdaptor_Curve.cxx
The line I'm wondering about is:
((GeomAdaptor_Curve*) (void*) &myCurve)->Load(C,First,Last);
myCurve is already defined as a GeomAdaptor_Curve. So it looks like it's casting a pointer to myCurve as a void*, and then casting that as a GeomAdaptor_Curve*, and then dereferencing it and calling Load on it. What possible reason could there be for doing that, rather than simply calling myCurve.Load?
Note that statement appears in a const member function. So the type of &myCurve is actually GeomAdaptor_Curve const*. This appears to be an ugly and confusing way to say
const_cast<GeomAdaptor_Curve&>(myCurve).Load(C,First,Last);
and may have been made more complicated in order to "avoid" compiler warnings you would get from attempting to use a C-style cast to circumvent const.
The only reason I could think of would be to ensure that a variable of the type "subclass of GeomAdaptor_Curve" was forced to call the Load function of the super-class.
The cast to void*, then on to GeomAdaptor_Curve*, would guarantee the type was treated as the latter, regardless of its actual type.
Having looked into the code, I can't see where this is a possibility so it's likely that it's either legacy code or something they've put in for future expansion.
It may be worthwhile contacting the dbarbier user on GitHub as they appear to have sole responsibility for changes (based on history).
Although, since that piece of code seems to be in the earliest GitHub versions, the original author may be a better bet, if you can find them (see the file header for one Remi LEQUETTE).
Related
In C++ it is possible to declare that a function is const, which means, as far as I understand, that the compiler ensures the function does not modify the object. Is there something analogous in C++ where I can require that a function is pure? If not in C++, is there a language where one can make this requirement?
If this is not possible, why is it possible to require functions to be const but not require them to be pure? What makes these requirements different?
For clarity, by pure I want there to be no side effects and no use of variables other than those passed into the function. As a result there should be no file reading or system calls etc.
Here is a clearer definition of side effects:
No modification to files on the computer that the program is run on and no modification to variables with scope outside the function. No information is used to compute the function other than variables passed into it. Running the function should return the same thing every time it is run.
NOTE: I did some more research and encountered pure script
(Thanks for jarod42's comment)
Based on a quick read of the wikipedia article I am under the impression you can require functions be pure in pure script, however I am not completely sure.
Short answer: No. There is no equivalent keyword called pure that constrains a function like const does.
However, if you have a specific global variable you'd like to remain untouched, you do have the option of static type myVar. This will require that only functions in that file will be able to use it, and nothing outside of that file. That means any function outside that file will be constrained to leave it alone.
As to "side effects", I will break each of them down so you know what options you have:
No modification to files on the computer that the program is run on.
You can't constrain a function to do this that I'm aware. C++ just doesn't offer a way to constrain a function like this. You can, however, design a function to not modify any files, if you like.
No modification to variables with scope outside the function.
Globals are the only variables you can modify outside a function's scope that I'm aware of, besides anything passed by pointer or reference as a parameter. Globals have the option of being constant or static, which will keep you from modifying them, but, beyond that, there's really nothing you can do that I'm aware.
No information is used to compute the function other than variables passed into it.
Again, you can't constrain it to do so that I'm aware. However, you can design the function to work like this if you want.
Running the function should return the same thing every time it is run.
I'm not sure I understand why you want to constrain a function like this, but no. Not that I'm aware. Again, you can design it like this if you like, though.
As to why C++ doesn't offer an option like this? I'm guessing reusability. It appears that you have a specific list of things you don't want your function to do. However, the likelihood that a lot of other C++ users as a whole will need this particular set of constraints often is very small. Maybe they need one or two at a time, but not all at once. It doesn't seem like it would be worth the trouble to add it.
The same, however, cannot be said about const. const is used all the time, especially in parameter lists. This is to keep data from getting modified if it's passed by reference, or something. Thus, the compiler needs to know what functions modify the object. It uses const in the function declaration to keep track of this. Otherwise, it would have no way of knowing. However, with using const, it's quite simple. It can just constrain the object to only use functions that guarantee that it remains constant, or uses the const keyword in the declaration if the function.
Thus, const get's a lot of reuse.
Currently, C++ does not have a mechanism to ensure that a function has "no side effects and no use of variables other than those passed into the function." You can only force yourself to write pure functions, as mentioned by Jack Bashford. The compiler can't check this for you.
There is a proposal (N3744 Proposing [[pure]]). Here you can see that GCC and Clang already support __attribute__((pure)). Maybe it will be standardized in some form in the future revisions of C++.
In C++ it is possible to declare that a function is const, which means, as far as I understand, that the compiler ensures the function does not modify the object.
Not quite. The compiler will allow the object to be modified by (potentially ill-advised) use of const_cast. So the compiler only ensures that the function does not accidentally modify the object.
What makes these requirements [constant and pure] different?
They are different because one affects correct functionality while the other does not.
Suppose C is a container and you are iterating over its contents. At some point within the loop, perhaps you need to call a function that takes C as a parameter. If that function were to clear() the container, your loop will likely crash. Sure, you could build a loop that can handle that, but the point is that there are times when a caller needs assurance that the rug will not be pulled out from under it. Hence the ability to mark things const. If you pass C as a constant reference to a function, that function is promising to not modify C. This promise provides the needed assurance (even though, as I mentioned above, the promise can be broken).
I am not aware of a case where use of a non-pure function could similarly cause a program to crash. If there is no use for something, why complicate the language with it? If you can come up with a good use-case, maybe it is something to consider for a future revision of the language.
(Knowing that a function is pure could help a compiler optimize code. As far as I know, it's been left up to each compiler to define how to flag that, as it does not affect functionality.)
This question has kind of been asked before but I feel the asker was hasty to call an answer correct when he never actually got a real answer. Maybe there is no reason why, and this needs to be put in the standard later, you tell me.
What is the rationale to not allow overloading of C++ conversions operator with non-member functions
I'm looking for the specific reason for this not being allowed as part of the design of the current standard. Basically, when you overload a cast operator to define an implicit conversion between two types, this overloaded definition has to be a member of the class that you're converting from, and not something outside a class. The obvious problem is that if you have types that you really can't modify for some reason but you want to implicitly convert between them for the sake of simplicity of syntax (despite the evils of implicit conversion) or because you have a bunch of other code, standard or custom that relies on implicit conversion...you can't do that if you can't add appropriate implicit conversions to the classes, so you need to use workarounds like regular functions for conversion that you would wrap around what would otherwise be the convenience of implicit conversion.
Also, is it...really possible that there would be a computational overhead to add these conversions outside a class? The way I see it, it would be easy for a compiler to, when going through to figure out what functions are available, associate external implicit conversion functions with the class they convert from so that the code is executed like it were part of that class as far as efficiency goes. The only downside would be the extra work it has to do to make the initial association, which should be almost nothing.
I will not take "because the standard says so" or "because implicit conversions are bad" as an answer. Somebody surely had a reason when they wrote the actual standard.
(I'm not a huge expert, I'm still learning the language.)
Edit, response:
Well, I imagine the situation could be like, yes you change the header file, but what you don't do is overwrite the existing one because that would be terrible. You would create a new header file based on the old one to accomodate the changes. The assumption would be that the old code is already compiled in an object file and changing the header just tells the compiler there's additional code somewhere else that you added. It wouldn't change what the old code does because it's already compiled and doesn't depend on that (i.e. some vendor handed you object code and a header). If I could modify and recompile the code I would be using the conversion for, then you couldn't make me write the conversion function externally, I wouldn't do it, it's too confusing. You wouldn't have to search every header randomly for the right definitions; if I was writing the code myself I would make a custom header with a highly visible section where the stuff I added to the vendor-supplied header is, and said header would be relatively obvious as to which one it was because it would be associated with the related types, and the other headers would be named by their original names so you would know they weren't changed. And you would have a corresponding file that contains only the conversion definitions, so my modifications would be self-contained, separated from the original object code, and relatively easy to find. Of course that's apart from the actual struggle of figuring out in the code which conversion function applies. I think you can find a variety of cases where that's easy enough to determine and natural enough to use where it makes sense to add on to an existing library like this for your own purposes. If I was using commercial code that I couldn't really modify and I saw a situation where what I was doing with it could be improved by using a conversion function to integrate it with some of my own stuff, I could see myself wanting to do this. Granted such things aren't obvious for a third person just reading a = b, they wouldn't know what was going on with my conversions just from that, but if you knew and it read nicely then it could work.
I appreciate the insight on how standards decisions tend to work, this is definitely a kind of fringe thing that you could ignore.
Besides having non-explicit conversion operators e.g. operator bool() in a class, you can also have non-explicit constructors taking a single argument, in the class you are converting to, as a way of introducing a user-defined conversion. (Not mentioned in question)
As to why you cannot introduce user-defined conversions between two types A and B without modifying their definitions... well this would create chaos.
If you can do this, then you can do it in a header file, and since introducing new user-defined conversions can change the meaning of code, it would mean that "old" code using only A and B could totally change what it is doing depending on if your header is then included before it, or something like this.
It's already hard enough to figure out exactly what user-defined conversion sequences are taking place when things are going wrong, even with the restriction that the conversions have to be declared by one of the two types. If you literally have to search every single unrelated header file in full potentially to find these conversion function definitions it dramatically worsens the maintenance problem, and there doesn't appear to be any benefit to allowing this. I mean can you give a non-contrived example where this language feature would help you make the implementation of something much simpler or easier to read?
In general, I think programmers like the idea that to figure out what a line a = b; does, they just have to read the definition of the type of a and the type of b and go from there... it's potentially ugly and painful if you start allowing these "gotcha" conversions that are harder to know about.
I guess you could say the same thing with regards to operator << being used for streaming... but with user-defined conversions its more serious since it can potentially affect any line of code where an object of that type is being passed as a parameter.
Also, I don't think you should necessarily expect to find a well-thought out reason, not everything that is feasible for compilers to implement is permitted by the standard. Committee tends to be conservative and seek consensus, so "no one really cared about feature X enough to fight for it" is probably as good an explanation as you will find about why feature X is not available.
Why is initialization of a constant dependent type in a template parameter list disallowed by the standard?
Answer to that question suggests a common reason for a feature not being available:
Legacy: the feature was left out in the first place and now we've built a lot without it that it's almost forgotten (see partial function template specialization).
Despite the fact that dynamic_cast returns a 0 if the pointer that is being handled is of an incompatible type, why would you avoid using dynamic_cast?
It takes non-zero runtime. That is about it. C-casts and their c++ counter parts like: reinterpret or static are 0-overhead because they are performed during compilation.
Well for some, important part might be that they do need RTTI, which also introduces some overhead, for example to the code size, because compiler has to include type information into binary, which is not normally done. One should take note that this might be non-standard option in the compilers.
Also relevant note from wiki: "In the original C++ design, Bjarne Stroustrup did not include run-time type information, because he thought this mechanism was frequently misused."
EDIT: Following on the quote and the comments. I am not sure if this is really a drawback, I would like to point out, that when you use it, you should think if you really do need it.
Some just dislike it, some do misuse it.
Run-time overhead:
More memory is needed to store RTTI (see link).
Types must be checked at runtime.
Design Issues:
Types involved must be polymorphic.
Is often a sign of something else wrong in your code; why do you need to check?
Does anyone know of any warnings that C++ compilers provide that help to enforce const correctness? For instance, it would be nice to have a warning produced by any C++ method that contains a non-const parameter that is never modified inside of the method. I see that there is a gnu compiler warning called -Wsuggest-attribute=const; however, when I use this flag I get an error saying that it is not recognized. Any ideas why?
I don't think such a warning exists, mostly because it would be useless. Just because a parameter is not modified inside the call, doesn't mean it should be made const just for the sake of it.
Think of virtual functions. Perhaps the designer of the base class, although not modifying the parameter in the base class, wants to leave it up to an extending class whether or not to modify that parameter.
Also, think of large applications, where modifying interfaces or API's or whatever costs a lot. You might not need to modify the parameter now, but intend to do so in the future. You're not going to make it const now, and force a full rebuild and probably risk errors in the future when you remove the const.
-Wsuggest-attribute=const
This analysis requires option
-fipa-pure-const
which is enabled by default at
-O
and higher
Careful, a const parameter like this one:
void myFunc(int const param);
does not belong to the interface. It belongs to the local scope of the function implementation. In fact, this function:
int inc(int const param) { return param+1; }
may be declared as
int inc(int param);
It is not a violation of the const correctness paradigm to claim the right to modify a variable but not actually do it.
If you are worried about const_cast you can either not use it in the first place or simply grep for it in your code base.
No, unfortunately there are no such warnings. You just get errors if you try to change const declared parameters. This is because missing const declarations do not change the correctness of the code from the compilers point of view. But const correctness is important for the compiler to discover potential optimizations and it improves the readability of the code. It is a matter of professionalism. Especially when using references const correctness is a must. I often refer to this.
The compiler itself takes const correctness very serious when operators (assignement, conversion, ...) come into play. A missing const here and the compiler refuses to use the operator because it makes a big difference if the given parameter may possibly be modified or not.
I'm not aware of such warnings and I think they would be rather hard to implement in a compiler - that is, they would slow it down. Maybe some static analysis tools have such features (but I'm not aware of those either).
As per Wsuggest-attribute=const, that is a different thing. It will suggest to use a gcc-specific "function attribute const", which is, basically, a mathematical function, receiving only values (no pointers), not reading or changing any static/global state and returning only a value (no pointers). For further description, look here: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
http://codepad.org/etWqYnn3
I'm working on some form of a reflexion system for C++ despite the many who have warned against. What I'm looking at having is a set of interfaces IScope, IType, IMember, IMonikerClient and a wrapper class which contains the above say CReflexion. Ignoring all but the member which is the important part here is what I would like to do:
1) Instance the wrapper
2) Determine which type is to be used
3) Instance type
4) Overload the () and [] to access the contained member from outer(the wrapper) in code as easily as it is done when using a std::vector
I find that using 0x I can forward a method call with any type for a parameter. I can't however cast dynamically as cast doesn't take a variable(unless there are ways I am unaware of!)
I linked the rough idea above. I am currently using a switch statement to handle the varying interfaces. I would, and for obvious reasons, like to collapse this. I get type match errors in the switch cases as a cause of the call to the methods compiling against each case where only one of three work for any condition and compiler errors are thrown.
Could someone suggest anything to me here? That is aside from sticking to VARIANT :/
Thanks!
C++, even in "0x land", simply does not expose the kind of information you would need to create something like reflection.
I find that using 0x I can forward a method call with any type for a parameter.
You cannot forward a type as a parameter. You can forward the const-volatile qualifiers on a member, but that's all done in templates, at compile time. No runtime check ever is done when you're using things like forward.
Your template there for operator() is not going to compile unless T is convertable to int*, string*, and A** all at once. Think of templates as a simple find and replace algorithm that generates several functions for you -- the value of T gets replaced with the typename when the template is instantiated, and the function is compiled as normal.
Finally, you can only use dyanmic_cast to cast down the class hierarchy -- casting between the completely unrelated types A B and C isn't going to operate correctly.
You're better off taking the time to rethink your design such that it doesn't use reflection at all. It will probably be a better design anyway, considering even in language with reflection, reflection is most often used to paper over poor designs.