where to place * in pointer type

Pages: 1234
vlad from moscow
You clearly haven't used C.
So you're saying that the * in int * is not part of the type?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

template <typename T>
void print(T t)
{
    std::cout << t << std::endl;
}

int main()
{
    int* p = new int();
    print(p);
    delete p;
}


If * were not part of the type, this would not compile. The template is instantiated with the type int*, not just int. So clearly the * counts as part of the type, unless you're saying that typename does not indicate a type name...

By the way, there is no language called C/C++.
closed account (o1vk4iN6)
What he means it's not part of the type for the declaration:

1
2
3
4
5

int* p1, p2;

p2 = new int; // error


C++ is a superset of C, so when someone says C/C++ they probably mean a feature present in both languages. As C++ was derived from an older standard of C, there may be some features that are not shared amongst the newest standards.
Last edited on
I just found this in the standard:

int // int i
int * // int *pi
int *[3] // int *p[3]
int (*)[3] // int (*p3i)[3]
int *() // int *f()
int (*)(double) // int (*pf)(double)
name respectively the types “int,” “pointer to int,” “array of 3 pointers to int,” “pointer to array
of 3 int,” “function of (no parameters) returning pointer to int,” and “pointer to a function of (double)
returning int.”


This is proof that there is a type "pointer to int."

Incidentally, this section uses int *p syntax. However, other parts of the standard use int* p.
closed account (o1vk4iN6)
1
2
3

int ********** dealwithit;


So int ********* is a type
So int ******** is a type
So int ******* is a type
So int ****** is a type
etc...
Last edited on
If you want to talk about Types in there broadest meaning, then there are two kinds of type, fundamental and compound. At this level, types describe objects, references, and functions.

Fundamental types are your plain old int, char etc.

Compound types are arrays, functions, pointers references classes unions enums and ... I think there are others.

So yes, something of the form T* is a Compound type.

So having said that we are talking about declarations. They take the form of T D, where T is the type and D is the declaritor. According to the standard, the * is part of the declaritor side not the type side (that is what I mean when I say it is not part of the type).

Now throw const into the mix: char const * const char_ptr...
Last edited on
> there is a type "pointer to int."

Most certainly, yes. If that was not the case,
1
2
int i = 8 ;
&i ; // *** compile time error - every expression must have a (static) type 


> int ********* is a type

Yes. Each * modifies the type just before it.

The specifiers indicate the type, storage class or other properties
of the entities being declared. The declarators specify the names of these entities and (optionally) modify
the type of the specifiers with operators such as * (pointer to) and () (function returning). - IS


So:
1
2
3
4
5
6
7
8
9
int integer = 0 ;

std::add_pointer<int>::type pointer = &integer ;
decltype( &integer ) another_pointer = &integer ;
decltype( std::unique_ptr<int>().get() ) a_third_pointer = &integer ;

assert( typeid(int*) == typeid( decltype( &std::vector<int>(5).front() ) ) ) ;
assert( typeid(int********) != typeid(int*********) );
// etc... 

@Telion

So you're saying that the * in int * is not part of the type?


It seems you can not read.:) I said that int * is not a type-specifier. Your problem that you did not ever read C/C++ standards. So you do not know what is a type-specifier and what is a declarator.


Last edited on

@kbw
vlad from moscow
You clearly haven't used C.


I do not think that your fantasy is interesting for anybody.
Please tell me, what has type-specifier and declarator to do with where * is placed?
* belongs to a declarator. For example

int x, *p, f( int, int ), ( *g )( char );
Last edited on
The standard just says how the language should work. It has nothing to do with how to format the code.
Well then you are trying to use a style that contradicts the C++ grammar. It is a very bad style. It is used by programmers with little experience. As a result you require that each declaration will be written in separate lines. Any such restrictions demonstrate already that your style is bad. As I pointed above many Microsoft declarations of API uses for example the following constructions

1
2
3
4
5
typedef struct
{
   int x;
   int y;
} TUPLE, *PTUPLE;


This can be seen very often in many headers especially written in C.
Also for a local class when it is used only inside a block it is better to use this syntax. For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
	class A
	{
	public:
		A( int i = 0 ) : x( i ) {}
		bool operator !() const { return ( x % 2 == 0 ); }
	private:
		int x;
	} a1( 5 ), a2( 10 );

	if ( !a1 ) std::cout << "a1 is even\n";
	else std::cout << "a1 is odd\n";

	if ( !a2 ) std::cout << "a2 is even\n";
	else std::cout << "a2 is odd\n";
}


There is no any need to separate the definition of class from the definition of objects of this class.

And as I also said early such declarations as

int* a, b;

only confuse readers. So you ought to write each declaration in a separate line. However there are such big functions that each declaration in a separate line makes it difficult to read.
For example it is better to declare logically associated variables in one line.

int weight, height;

or

Point p( 10, 10 ), &ref_p = p;
Last edited on
vlad, the standard is not a textbook (as you've seen back at http://cplusplus.com/forum/general/72273/ ), and is definitely not a best practices book or a coding style guide.

It describes the language, but it does not tell how to use it. Only the combined experience of the people and companies who actually *use* the language, after many man-years spent in maintenance and refactoring, can say what is good and what is not. Your suggested usage is exactly what's considered bad style by most experienced C++ users.
@Cubbi
Your suggested usage is exactly what's considered bad style by most experienced C++ users.


It is your illusion and nothing more. And as italian say ..parole, parole, parole and nothing more.
I demonstarted by examples that your style is bad moreover is very bed.. You only are repeating "parole".
Last edited on
How do you conclude that a declarator must be placed with the name of the object? This obviously doesn't work for declarators other than pointers and references. int *constp; is incorrect.

There is no language called "C/C++". However, the C++11 standard has a wonderful thing called the as-if rule which allows us to talk about C++ in plain English instead of standardspeak. It's not fair to deliberately refer to terms that most people have never seen before.

The standard itself is inconsistent in how it places the *. I've seen it done both ways in the same logical line of code.

No matter which way is better, you can't honestly tell me that int x, *p, f( int, int ), ( *g )( char ); is good style. Declaring variables of multiple types on the same line is just dumb and is never needed in C++11.
closed account (o1vk4iN6)
If someone wanted to they can write everything on one line, or each on it's own line:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

int
weight
;

int
main
(
int
argc
,
char
*
args
[]
)
{
return
0
;
}
/*
v
a
l
i
d

c
/
c++

p
r
o
g
r
a
m
*/


It's simply a matter of what makes it easier to read and what people are more logically to interpret it does.

If you have an empty function how do you place the brackets?

personally i prefer this, to me it makes it easy to see it's empty:

1
2
3
4
5

void func()
{
}
Last edited on

@Telion

No matter which way is better, you can't honestly tell me that int x, *p, f( int, int ), ( *g )( char ); is good style. Declaring variables of multiple types on the same line is just dumb and is never needed in C++11.



I have not understood what you said because it seems you do not understand what we are talking about. I never said that such deckaration

int x, *p, f( int, int ), ( *g )( char );

is a good style. I demonstrated what is a type specifier and what is a declarator.
I think you are unable to understand what we are speaking about in spite of my bad English.

So I simply ignore your comment because it is very foolish and does not deserve any discussion..

Last edited on
closed account (o1vk4iN6)
Telion wrote:
There is no language called "C/C++"


There is indeed a language called "C/C++", let us dissect this using our english.


The slash is most commonly used as the word substitute for "or" which indicates a choice (often mutually exclusive) is present. (Examples: Male/Female, Y/N, He/She.


http://en.wikipedia.org/wiki/Slash_(punctuation)

In other words: "C or C++".

So let us see what you are actually saying:

Telion wrote:
There is no language called C or C++


Quite silly, yes ?
Last edited on
@xerzi
It's simply a matter of what makes it easier to read and what people are more logically to interpret it does.


These are good words.

The declaration

int* a, b;

confuses readers of the code as I was convinced many times.
So what do apologists of this style say? They agree that it is a bad style so they suggest to write each declaration in a separate line.
But why should we write each declaration in a separate line because they select a bad style?! I do not understand this. It is their problem not main.:)


Moreover if you deal with big projects you know that very often it is not important what type has a single variable. It is important how variables are connected with each other. For example let assume that there are declarations

SomeQueue node;

and

SomeQueue *pnode;

If they are in different lines I need to check that they are have the same base type. It is not a problem if there are only two such declarations. But let assume that there are many queues, for example

AnotherQueue anode;
AnotherQueue *panode;

OneMoreQueue onode;
OneMoreQueue *ponode;

So then I am investigating some snip of code I do not know what is the connection between variables. I should always return to their declarations and consider all lines where for example AnotherQueue anode; and AnotherQueue *panode; are present. The worst that the two declarations can be in separate screens. It is very inconvenient. But if these two declarations would be on the same line it makes reading of code easy.

SomeQueue node, *pnode;
AnotherQueue anode, *panode;
OneMoreQueue onode, *ponode;

I would know that each two variables are connected with each other.

Do not forget that sometimes declarations occupy more than 20 or even 30 and more lines in C. I do not want scroll screens that to find out that onode and ponode have the same base type.
And at last what about declarations of function pointers?!:) How do the apologists declare them? Of course they declare them as

int ( *f )( int, int );

Even this contradicts their style because there is not such construction as int* in this declaration
Here int is a type specifier and ( *f )( int, int ) is a declarator. The same valid for declaration

int *p;

Here int is a type specifier and *p is a declarator.

So they use a bad style and try to invent some restrictions as to write each declarations in a separate line that their style will look more or less acceptable.:)

Last edited on
Pages: 1234