Can parentheses take arbitrary identifiers as arguments? C++ - c++

For example, is
(const int)* someInt;
valid code?
If so, is that statement different than
const int* someInt;
?

You can put arbitrarily many parentheses around expressions without changing the meaning. But you cannot do the same with types. In particular, as the others have pointed out, the parenthese in your code change the meaning from a declaration to a cast.

You can do a c style cast with any type inside, but the expression that you are trying to cast may not be able to be casted that way.
You can't have any arbitrary type on the right hand side of a cast. You need a user defined conversion operator to perform the conversion.

This seems for me valid, because you can have everytime a pointer to an constant value.
I don't think that between the two exists an difference.

if someInt is defined as
int *someInt;
then
(const int)* someInt;
is valid. Else you will encounter error.
You deference a pointer to int and cast the resulting value to const int.
And yes, this statement without an assignment, is wasted.
int rtn = (const int)* someInt;

Related

Why can you do this conversion?

Why can you do this:
class Dummy {
double i,j;
};
class Addition {
int x,y;
public:
Addition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};
int main () {
Dummy d;
Addition * padd;
padd = (Addition*) &d;
cout << padd->result();
return 0;
}
Why is padd = (Addition*) &d; valid when it will generate a run-time error whenever it gets used afterwards? A quote from cplusplus.com:
Unrestricted explicit type-casting allows to convert any pointer into
any other pointer type, independently of the types they point to.
But why can you convert any pointer into any other pointer type just if you precede the reference with a casting operator?
Talking about that casting operator, how can it convert all types to another type? Does it call a conversion constructor because if so, I do not get it, because both Dummy nor Addition do not have a conversion constructor so how does this operation work then? How many operators does it have and is it the parentheses that are the operator itself, like = is an operator.
These kinds of casts are C style casts, and will let you cast just about anything to anything else. A cast is a statement to the compiler to disregard it's type safety rules and trust that you know best. This is sometimes necessary when the type system can't have all the information it needs to reach the right conclusions. However, if you are lying to the compiler about something's type, then you are producing undefined behavior.
In c++, you should avoid preforming C style casts and prefer the safer c++ alternatives (listed here. Theses casts can't completely protect you from yourself, but they do allow you to communicate the kind of cast you want to preform. Using this extra information, the compiler can warn you if your casts would do something other than what you expect them to do.
When you use:
padd = (Addition*) &d;
the compiler assumes that you, the person in charge, know what you are doing. If you shoot yourself in the foot, that's of your own choosing. The compiler is happy to let you do that.
If you would like the compiler to prevent you from such accidental, shoot-yourself-in-the-foot, situations, use static_cast.
padd = static_cast<Addition*>(&d);
The compiler will let you know that that is not OK.
If you use a C style cast, there is no check for errors or compatibility between the pointers. Also, I think you misunderstand the purpose of the unary operator &, in this case it gives the address of d and is not related to references.
Objects in memory are just bits that the program knows to be some type, if you tell it that it is another type it will not affect anything in the variable.

Parentheses and unpacking variadic template parameters [duplicate]

For example, is
(const int)* someInt;
valid code?
If so, is that statement different than
const int* someInt;
?
You can put arbitrarily many parentheses around expressions without changing the meaning. But you cannot do the same with types. In particular, as the others have pointed out, the parenthese in your code change the meaning from a declaration to a cast.
You can do a c style cast with any type inside, but the expression that you are trying to cast may not be able to be casted that way.
You can't have any arbitrary type on the right hand side of a cast. You need a user defined conversion operator to perform the conversion.
This seems for me valid, because you can have everytime a pointer to an constant value.
I don't think that between the two exists an difference.
if someInt is defined as
int *someInt;
then
(const int)* someInt;
is valid. Else you will encounter error.
You deference a pointer to int and cast the resulting value to const int.
And yes, this statement without an assignment, is wasted.
int rtn = (const int)* someInt;

How does a complex C style type casting expression work?

I was looking for a way to uppercase a standard string. The answer that I found included the following code:
int main()
{
// explicit cast needed to resolve ambiguity
std::transform(myString.begin(), myString.end(), myString.begin(),
(int(*)(int)) std::toupper)
}
Can someone explain the casting expression “(int(*) (int))”? All of the other casting examples and descriptions that I’ve found only use simple type casting expressions.
It's actually a simple typecast - but to a function-pointer type.
std::toupper comes in two flavours. One takes int and returns int; the other takes int and const locale& and returns int. In this case, it's the first one that's wanted, but the compiler wouldn't normally have any way of knowing that.
(int(*)(int)) is a cast to a function pointer that takes int (right-hand portion) and returns int (left-hand portion). Only the first version of toupper can be cast like that, so it disambiguates for the compiler.
(int(*)(int)) is the name of a function pointer type. The function returns (int), is a function *, and takes an (int) argument.
As others already mentioned, int (*)(int) is the type pointer to a function which takes and returns int. However what is missing here is what this cast expression does: Unlike other cast expressions it does not really cast (i.e. it does not convert a value into a different type), but it selects from the overloaded set of functions named std::toupper the one which has the signature int(int).
Note, however, that this method is somewhat fragile: If for some reason there's no matching function (for example because the corresponding header was not included) but only one non-matching function (so no ambiguity arises), then this cast expression will indeed turn into a cast, more exactly a reinterpret_cast, with undesired effects. To make sure that no unintended cast happens, the C++ style cast syntax should be used instead of the C style cast syntax: static_cast<int(*)(int)>(std::toupper) (actually, in the case of std::toupper this case cannot occur because the only alternative function is templated and therefore ambiguous, however it could happen with other overloaded functions).
Coincidentally, the new-style cast syntak is more readable in that case, too.
Another possibility, which works without any cast expression, is the following:
int (*ptoupper)(int) = &std::toupper; // here the context provides the required type information
std::transform(myString.begin(), myString.end(), myString.begin(), ptoupper);
Note that the reason why the context cannot provide the necessary information is that std::transform is templated on the last argument, therefore the compiler cannot determine the correct function to choose.
int function(int);
A function taking int and returning int.
int (*function_pointer)(int);
A pointer to a function taking int and returning int.
int (*)(int)
The type of a pointer to a function taking int and returning int.
std::toupper from <cctype> already has type int (*)(int), but the one in <locale> is templatized on charT, which I assume is the reason for the cast. But ptr_fun would be clearer.

good way to write "pointer to something" in C/C++

Is there a "good" way to write "pointer to something" in C/C++ ?
I use to write void foo( char *str ); But sometimes I find it quite illogical because the type of str is "pointer to char", then it should more logical to attach the * to the type name.
Is there a rule to write pointers ?
char*str;
char* str;
char *str;
char * str;
There is no strict rule, but bear in mind that the * attaches to the variable, so:
char *str1, *str2; // str1 and str2 are pointers
char* str1, str2; // str1 is a pointer, str2 is a char
Some people like to do char * str1 as well, but it's up to you or your company's coding standard.
The common C convention is to write T *p, whereas the common C++ convention is to write T* p. Both parse as T (*p); the * is part of the declarator, not the type specifier. It's purely an accident of pointer declaration syntax that you can write it either way.
C (and by extension, C++) declaration syntax is expression-centric; IOW, the form of a declaration should match the form of an expression of the same type in the code.
For example, suppose we had a pointer to int, and we wanted to access that integer value. To do so, we dereference the pointer with the * indirection operator, like so:
x = *p;
The type of the expression *p is int; thus, it follows that the declaration of p should be
int *p
The int-ness of p is provided by the type specifier int, but the pointer-ness of p is provided by the declarator *p.
As a slightly more complicated example, suppose we had a pointer to an array of float, and wanted to access the floating point value at the i'th element of the array through the pointer. We dereference the array pointer and subscript the result:
f = (*ap)[i];
The type of the expression (*ap)[i] is float, so it follows that the declaration of the array pointer is
float (*ap)[N];
The float-ness of ap is provided by the type specifier float, but the pointer-ness and array-ness are provided by the declarator (*ap)[N]. Note that in this case the * must explicitly be bound to the identifer; [] has a higher precedence than unary * in both expression and declaration syntax, so float* ap[N] would be parsed as float *(ap[N]), or "array of pointers to float", rather than "pointer to array of float". I suppose you could write that as
float(* ap)[N];
but I'm not sure what the point would be; it doesn't make the type of ap any clearer.
Even better, how about a pointer to a function that returns a pointer to an array of pointer to int:
int *(*(*f)())[N];
Again, at least two of the * operators must explicitly be bound in the declarator; binding the last * to the type specifier, as in
int* (*(*f)())[N];
just indicates confused thinking IMO.
Even though I use it in my own C++ code, and even though I understand why it became popular, the problem I have with the reasoning behind the T* p convention is that it just doesn't apply outside of the simplest of pointer declarations, and it reinforces a simplistic-to-the-point-of-being-wrong view of C and C++ declaration syntax. Yes, the type of p is "pointer to T", but that doesn't change the fact that as far as the language grammar is concerned * binds to the declarator, not the type specifier.
For another case, if the type of a is "N-element array of T", we don't write
T[N] a;
Obviously, the grammar doesn't allow it. Again, the argument just doesn't apply in this case.
EDIT
As Steve points out in the comments, you can use typedefs to hide some of the complexity. For example, you could rewrite
int *(*(*f)())[N];
as something like
typedef int *iptrarr[N]; // iptrarr is an array of pointer to int
typedef iptrarr *arrptrfunc(); // arrptrfunc is a function returning
// a pointer to iptrarr
arrptrfunc *f; // f is a pointer to arrptrfunc
Now you can cleanly apply the T* p convention, declaring f as arrptrfunc* f. I personally am not fond of doing things this way, since it's not necessarily clear from the typedef how f is supposed to be used in an expression, or how to use an object of type arrptrfunc. The non-typedef'd version may be ugly and difficult to read, but at least it tells you everything you need to know up front; you don't have to go digging through all the typedefs.
The "good way" depends on
internal coding standards in your project
your personal preferences
(probably) in that order.
There is no right or wrong in this. The important thing is to pick one coding standard and stick to it.
That being said, I personally believe that the * belongs with the type and not the variable name, as the type is "pointer to char". The variable name is not a pointer.
I think this is going to be heavily influenced by the general pattern in how one declares the variables.
For example, I have a tendency to declare only one variable per line. This way, I can add a comment reminding me how the variable is to be used.
However, there are times, when it is practical to declare several variables of the same type on one line. Under such circumstances, my personal coding rule is to never, NEVER, EVER declare pointers on the same line as non-pointers. I find that mixing them can be a source of errors, so I try to make it easier to see "wrongness" by avoiding mixing.
As long as I follow the first guideline, I find that it does not matter overly much how I declare the pointers so long as I am consistent.
However, if I use the second guideline and declare several pointers on the same line, I find the following style to be most beneficial and clear (of course others may disagree) ...
char *ptr1, *ptr2, *ptr3;
By having no space between the * and the pointer name, it becomes easier to spot whether I have violated the second guideline.
Now, if I wanted to be consistent between my two personal style guidelines, when declaring only one pointer on a line, I would use ...
char *ptr;
Anyway, that's my rationale for part of why I do what I do. Hope this helps.

Why would you cast the lhs of an assignment?

I came across some code that boils down to the following:
enum BAR { /* enum values omitted */ }
class Foo{
public:
void set(const BAR& bar);
private:
uint32_t bits;
};
void Foo::set(const BAR& bar)
{
(uint32_t&)bits = bits | bar;
}
I don't understand the point of the c-style cast in the assignment in Foo::set. Why would you cast the lhs of an assignment? Am I crazy, or does this have a purpose?
In this case, I can't see any reason for the cast, as the thing being cast is of the same type as the cast. In general, it could be used to force a particular assignement operator to be used.
I will now repeat my mantra: If your code contains casts, there is probably something wrong with the code or the design and you should examine both with a view to removing the cast.
I agree with Neil Butterworth, the cast in this case isn't necessary and it is a definite "code smell".
It does nothing at all, as far as I can tell, even if BAR is defined with values outside the uint32 range. Looks like noise to me.
I can't say for sure without knowing the background, but it looks like someone may have taken some existing C code and wrapped it in a C++ class. The cast may be a leftover from the c code.
I'm not sure this is legal. a cast is not an lvalue...
Either way, it looks fairly pointless.
If you only want to permit certain value to be assigned (e.g., the checking on the assignment is done as if to variable typed as per the cast, instead of just letting anything go through as if you widened the rhs).