# C++ QuestionHelp with pointers

#### Enjo

##### Mostly harmless
Tutorial Publisher
Donator
Additionaly, I have just learned that you can't have an STL-collection of references, because you can't have a pointer to a reference... while of course a pointer to a pointer is common practice.
But, as a compromise, you can use a collection of unique or shared pointers, where the first takes care of automatic deallocation, and the latter does the same, plus kind of simulates Java/C# reference behavior.

Last edited:

#### jedidia

##### shoemaker without legs
But, as a compromise, you can use a collection of unique or shared pointers

Oh sure, I've been doing similar stuff for years. It was just now that I tried to make a vector of references because it seemed slightly more convenient in the situation (lots of objects with a livetime below a second and frequent instantiating), and noticed it doesn't actually work. Since there was a discussion of pointers vs. references going on, I thought it might be a good tidbit to throw in.

#### Col_Klonk

##### Member
Sorry no. As smart as you try to be, you can sure answer the following question easily: Which data types does assembler know and how strongly are they typed?
Strong typing is for high level compilers, Assembler doesn't care that much about types. As a developer it's up to you to make sure that you use the right type, although you can use the same variable as any type, many times as you wish.

Assember uses the few basic data types native to the cpu, Languages like C..etc have just renamed the types but they are the same thing, just like references and pointers are the same thing to the cpu (Indexed addressing).

I pointed out the Intel dev docs as it would help high level language developers understand the core cpu concepts better. Once you read through the docs it becomes very clear what pointers, data types.. etc are, and how they are used in any language. What any person will discover after reading the Intel manuals, is how languages like C, C++.. etc have made a mess of such a simple concept.. No wonder people have difficulty understanding it.

This stuff below is a few lines (of 51000+) of the Windows Include file (H file in C languages).. As one can see all the C definitions amount to nothing more than a few basic cpu types.
Code:
; ---------------------------
; C and C++ type definitions
; ---------------------------
CALLBACK                    typedef PROTO STDCALL
WINAPI                      typedef PROTO STDCALL

; 8 bit   BYTE
; ~~~~~
CHAR                        typedef BYTE
UCHAR                       typedef BYTE
;;; TBYTE                       typedef BYTE ; naming conflist with MASM data type

IFDEF __UNICODE__
TCHAR                       typedef WORD
ELSE
TCHAR                       typedef BYTE
ENDIF

bool                        typedef BYTE
BOOLEAN                     typedef BYTE

; 16 bit  WORD
; ~~~~~~
;;; SHORT                       typedef WORD
USHORT                      typedef WORD
ATOM                        typedef WORD
WCHAR                       typedef WORD
LANGID                      typedef WORD
OLECHAR                     typedef WORD
FILEOP_FLAGS                typedef WORD

; 32 bit  DWORD
; ~~~~~~
ABORTPROC                   typedef DWORD
ACMDRIVERENUMCB             typedef DWORD
ACMDRIVERPROC               typedef DWORD
ACMFILTERCHOOSEHOOKPROC     typedef DWORD
ACMFILTERENUMCB             typedef DWORD
ACMFILTERTAGENUMCB          typedef DWORD
ACMFORMATCHOOSEHOOKPROC     typedef DWORD
ACMFORMATENUMCB             typedef DWORD
ACMFORMATTAGENUMCB          typedef DWORD
NET_API_STATUS              typedef DWORD
API_RET_TYPE                typedef DWORD
APPLET_PROC                 typedef DWORD
BOOL                        typedef DWORD
CALINFO_ENUMPROC            typedef DWORD
COLORREF                    typedef DWORD
;;; CONST                       typedef DWORD   ; naming conflist with MASM reserve word
;;; CRITICAL_SECTION            typedef DWORD   ; naming conflist with structure
CTRYID                      typedef DWORD
DATEFMT_ENUMPROC            typedef DWORD
DESKTOPENUMPROC             typedef DWORD
DLGPROC                     typedef DWORD
DRAWSTATEPROC               typedef DWORD
EDITWORDBREAKPROC           typedef DWORD
ENHMFENUMPROC               typedef DWORD
ENUMRESLANGPROC             typedef DWORD
ENUMRESNAMEPROC             typedef DWORD
ENUMRESTYPEPROC             typedef DWORD
FARPROC                     typedef DWORD
FILE_SEGMENT_ELEMENT        typedef DWORD
FONTENUMPROC                typedef DWORD
GOBJENUMPROC                typedef DWORD
GRAYSTRINGPROC              typedef DWORD
HACCEL                      typedef DWORD
HANDLE                      typedef DWORD
HBITMAP                     typedef DWORD
HBRUSH                      typedef DWORD
HCOLORSPACE                 typedef DWORD
HCONV                       typedef DWORD
HCONVLIST                   typedef DWORD
HCURSOR                     typedef DWORD
HDC                         typedef DWORD
HDDEDATA                    typedef DWORD
HDESK                       typedef DWORD
HDROP                       typedef DWORD
HDWP                        typedef DWORD
HENHMETAFILE                typedef DWORD
HFILE                       typedef DWORD
HFONT                       typedef DWORD
HGDIOBJ                     typedef DWORD
HGLOBAL                     typedef DWORD
HHOOK                       typedef DWORD
HICON                       typedef DWORD
HIMAGELIST                  typedef DWORD
HIMC                        typedef DWORD
HINSTANCE                   typedef DWORD
HKEY                        typedef DWORD
HKL                         typedef DWORD
HLOCAL                      typedef DWORD
HMETAFILE                   typedef DWORD
HMODULE                     typedef DWORD
HMONITOR                    typedef DWORD
HOOKPROC                    typedef DWORD
HPALETTE                    typedef DWORD
HPEN                        typedef DWORD
HRGN                        typedef DWORD
HRSRC                       typedef DWORD
HSZ                         typedef DWORD
HTREEITEM                   typedef DWORD
HWINSTA                     typedef DWORD
HWND                        typedef DWORD
;;; INT                         typedef DWORD; naming conflist with MASM reserve word
LCID                        typedef DWORD
LCSCSTYPE                   typedef DWORD
LCSGAMUTMATCH               typedef DWORD
LCTYPE                      typedef DWORD
LINEDDAPROC                 typedef DWORD
LOCALE_ENUMPROC             typedef DWORD
LONG                        typedef DWORD
LPARAM                      typedef DWORD
LPBOOL                      typedef DWORD
LPBYTE                      typedef DWORD
LPCCHOOKPROC                typedef DWORD
LPCFHOOKPROC                typedef DWORD
LPCOLORREF                  typedef DWORD
LPCRITICAL_SECTION          typedef DWORD
LPCSTR                      typedef DWORD
LPCTSTR                     typedef DWORD
LPCVOID                     typedef DWORD
LPCWSTR                     typedef DWORD
LPDWORD                     typedef DWORD
LPFIBER_START_ROUTINE       typedef DWORD
LPFRHOOKPROC                typedef DWORD
LPHANDLE                    typedef DWORD
LPHANDLER_FUNCTION          typedef DWORD
LPINT                       typedef DWORD
LPLONG                      typedef DWORD
LPOFNHOOKPROC               typedef DWORD
LPOLESTR                    typedef DWORD
LPCOLESTR                   typedef DWORD
LPPAGEPAINTHOOK             typedef DWORD
LPPAGESETUPHOOK             typedef DWORD
LPPRINTHOOKPROC             typedef DWORD
LPPROGRESS_ROUTINE          typedef DWORD
LPSETUPHOOKPROC             typedef DWORD
LPSTR                       typedef DWORD
LPSTREAM                    typedef DWORD
LPTSTR                      typedef DWORD
LPVOID                      typedef DWORD
LPWORD                      typedef DWORD
LPWSTR                      typedef DWORD
LRESULT                     typedef DWORD
;;; LUID                        typedef DWORD   ; name conflict with structure
MCIDEVICEID                 typedef DWORD
PBOOL                       typedef DWORD
PBOOLEAN                    typedef DWORD
PBYTE                       typedef DWORD
PCHAR                       typedef DWORD
PCRITICAL_SECTION           typedef DWORD
PCSTR                       typedef DWORD
PCTSTR                      typedef DWORD
PCWCH                       typedef DWORD
PCWSTR                      typedef DWORD
PDWORD                      typedef DWORD
PFLOAT                      typedef DWORD
PFNCALLBACK                 typedef DWORD
PHANDLE                     typedef DWORD
PHANDLER_ROUTINE            typedef DWORD
PHKEY                       typedef DWORD
PINT                        typedef DWORD
PLCID                       typedef DWORD
PLONG                       typedef DWORD
PLUID                       typedef DWORD
PROPENUMPROC                typedef DWORD
PROPENUMPROCEX              typedef DWORD
PSHORT                      typedef DWORD
PSTR                        typedef DWORD
PTBYTE                      typedef DWORD
PTCHAR                      typedef DWORD
PTIMERAPCROUTINE            typedef DWORD
PTSTR                       typedef DWORD
PUCHAR                      typedef DWORD
PUINT                       typedef DWORD
PULONG                      typedef DWORD
PUSHORT                     typedef DWORD
PVOID                       typedef DWORD
PWCHAR                      typedef DWORD
PWORD                       typedef DWORD
PWSTR                       typedef DWORD
REGISTERWORDENUMPROC        typedef DWORD
REGSAM                      typedef DWORD
SC_HANDLE                   typedef DWORD
SC_LOCK                     typedef DWORD
SCODE                       typedef DWORD
SENDASYNCPROC               typedef DWORD
SERVICE_STATUS_HANDLE       typedef DWORD
SOCKET                      typedef DWORD
TIMEFMT_ENUMPROC            typedef DWORD
TIMERPROC                   typedef DWORD
UINT                        typedef DWORD
ULONG                       typedef DWORD
WINSTAENUMPROC              typedef DWORD
WNDENUMPROC                 typedef DWORD
WNDPROC                     typedef DWORD
WPARAM                      typedef DWORD
YIELDPROC                   typedef DWORD

; 64 bit
; ~~~~~~
LONG64                      typedef QWORD
ULONG64                     typedef QWORD
INT64                       typedef QWORD
UINT64                      typedef QWORD
WORD64                      typedef QWORD
POINTER_64                  typedef QWORD
LONGLONG                    typedef QWORD
ULONGLONG                   typedef QWORD

; Floating point
; ~~~~~~~~~~~~~~
FLOAT                       typedef REAL4
DOUBLE                      typedef REAL8
;;; LONG DOUBLE                 typedef REAL10

; ----------------------------------------------

Last edited:

#### Urwumpe

##### Not funny anymore
Donator
Still you miss the important difference: Even even all C++ types are in the end corresponding to Intel assembler types (mandatory), the C++ language semantics go far beyond the assembler types. Assembler does for example not know signed or unsigned registers. The instructions make the difference.

And because high-level languages also encode requirements beyond the object code (Like strong-typing) it can even be that, despite two types being encoded in the same assembler instructions - they are not the same in the context of the higher level language. And that for a very good reason. They could change later. Or could be different on another architecture. Or you have different APIs working with these types.

#### Col_Klonk

##### Member
Assembler does for example not know signed or unsigned registers. The instructions make the difference.

The developer does and would use different instructions to deal with signed and unsigned. You have that freedom of choice - strong typing takes that freedom away.

You're mentioning cross-platform.. this has never worked out has planned, and certainly the main cause of buggy, inefficient code.

You'd have to change the API code with any code type changes anyway, no matter what platform is used.

Last edited:

#### Urwumpe

##### Not funny anymore
Donator
The developer does and would use different instructions to deal with signed and unsigned. You have that freedom of choice - strong typing takes that freedom away.

Wrong - strong typing ensures that you have the freedom to focus on more important things in life than maintaining simple conventions.

If a task is so stupid that a compiler can do it - why do it yourself?

#### Col_Klonk

##### Member
:lol:
Talk about going around in circles..

Indexed addressing is nothing but references and pointers, which are the same thing..

There are only a few data types on a cpu, no matter how a language decorates them.

The brain is the best optimising compiler.

Coding discipline ensures you're better than a compiler, and it take no more time than tapping a keyboard.

Letting compilers do the job you can do better makes you lazy.

Reading Intel manuals prevents silly arguments like this :thumbup:

#### Urwumpe

##### Not funny anymore
Donator
The brain is the best optimising compiler.

:rofl: :rofl: :rofl:

Such a hubris.

#### Fizyk

##### Member
Urwumpe said:
Still you miss the important difference: Even even all C++ types are in the end corresponding to Intel assembler types (mandatory), the C++ language semantics go far beyond the assembler types.
Col_Klonk said:
There are only a few data types on a cpu, no matter how a language decorates them.
Wait, what?

There are no types in assembler, or on a CPU. There are just bytes. Data types are higher-level constructs. On the lowest level, you just have raw bytes with meaning entirely dependent on usage.

#### Enjo

##### Mostly harmless
Tutorial Publisher
Donator
You're mentioning cross-platform.. this has never worked out has planned, and certainly the main cause of buggy, inefficient code.
Subjective. Besides the reality is that there are many working systems based on cross-platform-ism. Raspberry Pi would be a public example. The whole Embedded Linux industry would be another one, hidden behind the scenes.

Last edited:

#### Urwumpe

##### Not funny anymore
Donator
Subjective. Besides the reality is that there are many working systems based on cross-platform-ism. Raspberry Pi would be a public example. The whole Embedded Linux industry would be another one, hidden behind the scenes.

The most important computer systems are mostly multi-platform, because they are too large and too important to run on a single kind of hardware.

Also, multi-platform already starts such a small change like 32 bit linux vs 64 bit linux. If you have followed all best practises you will have no or little problems then. Never using int in C or C++ unless you really mean it is one example there. int is no 32 bit integer.

---------- Post added at 11:45 PM ---------- Previous post was at 11:42 PM ----------

Wait, what?

There are no types in assembler, or on a CPU. There are just bytes. Data types are higher-level constructs. On the lowest level, you just have raw bytes with meaning entirely dependent on usage.

Well, actually you have a kind of datatype equivalent with the register and register combinations. But yes, a CPU doesn't care much what you have in the register. Loading a 8 bit value into AH and then storing EAX as 32 bit value in the same place is legal. :lol:

#### Enjo

##### Mostly harmless
Tutorial Publisher
Donator
Subjective. Besides the reality is that there are many working systems based on cross-platform-ism. Raspberry Pi would be a public example. The whole Embedded Linux industry would be another one, hidden behind the scenes.
I forgot to add Android, Mac OS X and iOS. All inheriting from Unix, and using multiplaftorm to the bone GNU software. Here I must admit that it's buggy and oldschool, but not that buggy.

Also, multi-platform already starts such a small change like 32 bit linux vs 64 bit linux. If you have followed all best practises you will have no or little problems then. Never using int in C or C++ unless you really mean it is one example there. int is no 32 bit integer.
In high level programming that I do, it's assumed to use int, because I would like the programs to be able to compute longer data chains as CPU development progresses.

#### Urwumpe

##### Not funny anymore
Donator
In high level programming that I do, it's assumed to use int, because I would like the programs to be able to compute longer data chains as CPU development progresses.

Yes, but then you still need to remember that ints are not strictly defined and program accordingly. Which isn't easy all the time.

##### Scientist
If you really want an invariant length, then C++ 11 standard defines these flavors now:

Code:
Types
Defined in header <cstdint>
int8_t
int16_t
int32_t
int64_t

(optional)

signed integer type with width of exactly 8, 16, 32 and 64 bits respectively
with no padding bits and using 2's complement for negative values
(provided only if the implementation directly supports the type)
(typedef)
int_fast8_t
int_fast16_t
int_fast32_t
int_fast64_t

fastest signed integer type with width of at least 8, 16, 32 and 64 bits respectively
(typedef)
int_least8_t
int_least16_t
int_least32_t
int_least64_t

smallest signed integer type with width of at least 8, 16, 32 and 64 bits respectively
(typedef)
intmax_t

maximum width integer type
(typedef)
intptr_t

(optional)

integer type capable of holding a pointer
(typedef)
uint8_t
uint16_t
uint32_t
uint64_t

(optional)

unsigned integer type with width of exactly 8, 16, 32 and 64 bits respectively
(provided only if the implementation directly supports the type)
(typedef)
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t

fastest unsigned integer type with width of at least 8, 16, 32 and 64 bits respectively
(typedef)
uint_least8_t
uint_least16_t
uint_least32_t
uint_least64_t

smallest unsigned integer type with width of at least 8, 16, 32 and 64 bits respectively
(typedef)
uintmax_t

maximum width unsigned integer type
(typedef)
uintptr_t

(optional)

unsigned integer type capable of holding a pointer
(typedef)
Macro constants
Defined in header <cstdint>
Signed integers : minimum value
INT8_MIN
INT16_MIN
INT32_MIN
INT64_MIN

minimum value of an object of type int8_t, int16_t, int32_t, int64_t
(macro constant)
INT_FAST8_MIN
INT_FAST16_MIN
INT_FAST32_MIN
INT_FAST64_MIN

minimum value of an object of type int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t
(macro constant)
INT_LEAST8_MIN
INT_LEAST16_MIN
INT_LEAST32_MIN
INT_LEAST64_MIN

minimum value of an object of type int_least8_t, int_least16_t, int_least32_t, int_least64_t
(macro constant)
INTPTR_MIN

minimum value of an object of type intptr_t
(macro constant)
INTMAX_MIN

minimum value of an object of type intmax_t
(macro constant)
Signed integers : maximum value
INT8_MAX
INT16_MAX
INT32_MAX
INT64_MAX

maximum value of an object of type int8_t, int16_t, int32_t, int64_t
(macro constant)
INT_FAST8_MAX
INT_FAST16_MAX
INT_FAST32_MAX
INT_FAST64_MAX

maximum value of an object of type int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t
(macro constant)
INT_LEAST8_MAX
INT_LEAST16_MAX
INT_LEAST32_MAX
INT_LEAST64_MAX

maximum value of an object of type int_least8_t, int_least16_t, int_least32_t, int_least64_t
(macro constant)
INTPTR_MAX

maximum value of an object of type intptr_t
(macro constant)
INTMAX_MAX

maximum value of an object of type intmax_t
(macro constant)
Unsigned integers : maximum value
UINT8_MAX
UINT16_MAX
UINT32_MAX
UINT64_MAX

maximum value of an object of type uint8_t, uint16_t, uint32_t, uint64_t
(macro constant)
UINT_FAST8_MAX
UINT_FAST16_MAX
UINT_FAST32_MAX
UINT_FAST64_MAX

maximum value of an object of type uint_fast8_t, uint_fast16_t, uint_fast32_t, uint_fast64_t
(macro constant)
UINT_LEAST8_MAX
UINT_LEAST16_MAX
UINT_LEAST32_MAX
UINT_LEAST64_MAX

maximum value of an object of type uint_least8_t, uint_least16_t, uint_least32_t, uint_least64_t
(macro constant)
UINTPTR_MAX

maximum value of an object of type uintptr_t
(macro constant)
UINTMAX_MAX

maximum value of an object of type uintmax_t
(macro constant)
Function macros for minimum-width integer constants
INT8_C
INT16_C
INT32_C
INT64_C

expands to an integer constant expression having the value specified by its argument and the type int_least8_t, int_least16_t, int_least32_t, int_least64_t respectively
(function macro)
INTMAX_C

expands to an integer constant expression having the value specified by its argument and the type intmax_t
(function macro)
UINT8_C
UINT16_C
UINT32_C
UINT64_C

expands to an integer constant expression having the value specified by its argument and the type uint_least8_t, uint_least16_t, uint_least32_t, uint_least64_t respectively
(function macro)
UINTMAX_C

expands to an integer constant expression having the value specified by its argument and the type uintmax_t
(function macro)
Source

---------- Post added at 12:33 PM ---------- Previous post was at 12:31 PM ----------

When we recompile our apps for a new shiny IA128 bit architecture or IA256 bit architecture (because: huge!), we hope for the best that all will work ok, and then debug the rest!

#### Col_Klonk

##### Member
Ja.. that lot are just expansions on the 'raw' data types of the target cpu.
and macros as mentioned there in the comments.

BTW.. the brain is still the best optimiser.. enough programming experience bears this out
A compiler is only as good as the person who programs it... :tiphat:

#### Urwumpe

##### Not funny anymore
Donator
BTW.. the brain is still the best optimiser.. enough programming experience bears this out

Good luck optimizing more than 50,000 lines of code during a 30 day sprint. Maybe your brain will really be the better optimizer.

But the 99% solution of any good compiler is good enough for government work and two developers can really handle a small software project in typical release cycles easily (including having time during the work hours to design the next software project). When will your brain be done, in 5 years?

A compiler is only as good as the team which maintains it... :tiphat:

FIFY

#### Col_Klonk

##### Member
It looks like we're talking about different scenarios..

1) Those who know what they doing.

2) Those who profess to know what they doing.

Sat in a big meeting this morning and saw egos totally mess up a great idea.. :facepalm:

#### Urwumpe

##### Not funny anymore
Donator
Sat in a big meeting this morning and saw egos totally mess up a great idea.. :facepalm:

....by disagreeing with you?

As much as I can understand what you mean, I am in such meetings about every other week, but I consider such "egos" messing up my "great" ideas the result of me not communicating the great ideas....

• ... in the language that they understand.
• ... by giving them arguments, that their superiors can understand.
• ... to the persons that have the same perspective on the problem and the power to support me.

Also, as much as they can't see into my head and only get the 20% of the information that they understand from my communication, the same also applies to me: I can't always see what their view is like outside the meeting.

And it is good that way. Would I spend too much time thinking like business administrators, I would spend too little time thinking like a software developer.

(And I really hate being in such meetings. I am a software developer, no manager therapist.)

and BTW: A good solution applied with vigor now is better than a perfect solution applied ten minutes later.

Last edited:

#### Col_Klonk

##### Member
Wasn't my idea, but I could see the merits of it. I'll just let time take its course.

The usual office politics and empire building, something that would not effect me as I have my empire established and rock stable :lol:.

(I'm an electronics technician, hardware/firmware/applications developer plus technical manager of ..jeez.. 3 departments (of an international company) when the sh1t hits the fan :rofl

So I'm not really an armchair rocket scientist... I do have a brain cell or two.. I think!!

Edt: Don't ask me which company.. They only found me by fluke, and I intend to remain privately web anonymous.. but it is a BIG company.

Last edited:

#### kamaz

##### Unicorn hunter
In high level programming that I do, it's assumed to use int, because I would like the programs to be able to compute longer data chains as CPU development progresses.

Deviations from the Standard

double
double is only 32 bits wide and implemented in the same way as float

8-bit int with -mint8
With -mint8 int is only 8 bits wide which does not comply to the C standard. Notice that -mint8 is not a multilib option and neither supported by AVR-Libc (except stdint.h) nor by newlib.

https://gcc.gnu.org/wiki/avr-gcc

On AVR, address registers are 16-bit, while arithmetic registers are 8-bits.

Compiling with -mint8 results in 8-bit int and 16-bit void* mirroring the internal architecture of the CPU (as it should be theoretically).

However such setup would mess up a lot of existing code, notably by both shortening the
range of int and challenging the widespread assumption that the size of void* is equal to that of int (hey, x86 does this so everyone else must!)

So the compiler by default uses 16-bits ints which don't match internal CPU architecture and the generated code does heavy register shuffling and other magic, such as using address registers for arithmetic. Results in pretty messy code, which is why AVR programmers are told to take care when mixing int types.

Point is...

... C was designed on PDP-11 and mirrors a lot of internal architecture of that system (notably this is why it has ++ and --) which the creators wrongly thought to be universal.

... people nowadays are trained on x86 and are assuming that design quirks specific to x86 (i.e. over-use of EAX) apply universally

... the fact that we handle new embedded architectures by re-targeting gcc does not help either because people think that "gcc is gcc" and if so they can get away with what they can do on linux/x86... no they can't...

Replies
15
Views
388
Replies
32
Views
1K
Replies
4
Views
304
Replies
2
Views
438
Replies
1
Views
312