Ascend4nt Posted January 29, 2014 Share Posted January 29, 2014 I think this seals the deal. I'll never be ready for prime time when it comes down to c++. jaberwacky, Don't let pointer-to-pointer recursion dissuade you from learning a language. Pointers more than one level deep are just all-around messy and require a bit more care and thought from the programmer in trying to keep things straight and bug-free - both in their code and in their head! The trend with modern C++ is to avoid pointers completely because of the inherent dangers and possible false assumptions associated with them. If you use arrays in C++ now, you prefer to use std::array for arrays of predetermined size, std::vector for dynamic arrays, and Start/End Iterators (or possibly array_ref) for observing an array with a size determined during runtime. Still, the one problem every high-level language runs into with interfacing with the O/S, external APIs, and module files (DLLs in Windows) is that there is no easy way to interface with external code without a 'flattening' of the language code to at least C-level style pointers and functions. That's one of the reasons why you will see tons of wrapper classes for interfacing with external APIs - to maintain an abstraction and hide the ugly details of implementation. But hmm, back to the point..ers. When someone refers to a 'char *' as an array of characters (or a string), thats not entirely true. Nor is it true that 'char **' is always an array of string pointers. These are all assumptions that are made when looking at something in isolation. It's only when there is a given context that something more can be made of them. What I mean by this is that, given 'char *' in isolation, the only reasonable assumption you can make is that the variable contains a pointer to a character. One typically assumes that more characters follow, but this is not possible to determine from just a variable declaration. Likewise, 'char **' is a pointer to a pointer to a character, and so on. Each '*' is just one more level of indirection via a pointer. Without more information as to the context with which that occurs, and whether each level of indirection has more than one pointer (or character) in a row, one can only assume the pointer-to-pointer-to-etc relationship. So, given something like this: char *** CharDeepPtr; We know that: CharDeepPtr itself is a pointer. *CharDeepPtr (one level down) is ALSO a pointer **CharDeepPtr (2 down) is another pointer ***CharDeepPtr is a character. When people say that 'char ***' is an array of pointers to string pointers, they are making the assumption that: at EACH level prior to the 'bottom', there is more than one pointer in a row (array) at the bottom level, there are more than one character in a row, and together they form a string (also an array) Assumptions and facts aside though, what I'm trying to get across is that each extra asterisk represents one more pointer in between the variable and the data type declared on the left-hand side. Each pointer has its own declarative type certainly, but underneath it all it still is just a pointer. Want it to get even more messy and hard-to-decipher? Sprinkle some 'const' modifiers in, hah const char * const * const * const p = 0; // const pointer to const ptr to const ptr to const char! Luckily, the ambiguity of pointer-to-pointer variables and whether each level is an array (or just one element) is something you won't usually come across. Most modern code will strive to make things much more readable and understandable by using modern features, or at least some level of abstraction. You can usually get at least 2 levels of indirection (more is atypical) in C++ without it getting confusing and looking plain ugly, but there are still a few issues with the language.. Modern C++11 definition for a 2D array: std::array<std::array<int, 2>, 3> arr = {{{5, 8}, {8, 3}, {5, 3}}}; vs. old-style: int myArr[3][2] = {{5, 8}, {8, 3}, {5, 3}}; Still, on a whole, modern C++ is generally much more understandable and safe. Not as nice as D perhaps, but much better than C and C++98 code styles.. Xandy and jaberwacky 2 My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
jaberwacky Posted January 29, 2014 Share Posted January 29, 2014 Golly. Thanks for taking the time to write all that. So, I was right in my previous assumption about char***? It could be a pointer to a pointer to a pointer to a char but could also be what trancexx said which is most likely going to be correct. I definitely saw the advantage to trying to do away with pointers in my own programming journey a while back but guess I needed some validation from others who know more than me. Again, thanks for writing this informative ... article! Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
trancexx Posted January 30, 2014 Share Posted January 30, 2014 (edited) You can define one character as set/array of characters in size of 1.That's why it's allways valid to say that pointer to char is pointer to array of chars because the size of array is left undefined.You can write for one character:int a = 23; int* b = &a; // b is pointeror:int a[1] = { 23 }; int* b = a; // b is pointerIn both cases you have int* b that you can interpret both ways:auto c = *b; // c is int 23or (again in any of the cases above):auto c = b[0]; // c is int 23 Edited January 30, 2014 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Ascend4nt Posted January 30, 2014 Share Posted January 30, 2014 Golly. Thanks for taking the time to write all that. So, I was right in my previous assumption about char***? It could be a pointer to a pointer to a pointer to a char but could also be what trancexx said which is most likely going to be correct. jaberwacky, yes. It is one or the other depending on how you interpret it. And yw! I didn't realize that post was going to be that lengthy but it does resemble an article eh? You can define one character as set/array of characters in size of 1. That's why it's allways valid to say that pointer to char is pointer to array of chars because the size of array is left undefined. Really? Are you trying to screw with peoples' heads on purpose? Logically NO, a pointer is not truly an array until either a. you know the context in which it appears, or b. you go ahead and treat it as one regardless (as you have done). The latter is just absurd and dangerous, and really the '[]' operator is only syntactic sugar that results in the operation "*(arr + n)". If you want to falsely assume that if you can apply [] to any pointer, that it is then by default an array, then you are dead wrong and will wind up writing shit code that crashes. Granted, I'll give you that you can define an array as [1] element, but nobody in their right mind does that explicitly. Dynamically-defined and dynamically-allocated arrays can be and often start out as a length of 1 of course, but there again context is important. You need to know by some other piece of information that you indeed are looking at an array at any given level of indirection. This is why you'll want to prefer to use Containers (std::vector, std::string), Iterators, or some class (like array_ref and string_view) to make the type of data you are looking at clear. Sure, the old way is to pass a length along with a pointer, or to wrecklessly assume a certain length (as certain Windows API calls, and poorly written C/C++ code do) - but they are outdated methods that can cause all sorts of problems. Lets not try to confuse newcomers to the language, mmkay Xandy 1 My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
jaberwacky Posted January 30, 2014 Share Posted January 30, 2014 I didn't mean it was lengthy like an article but that it is informative like an article. <Grabs some popcorn and some hot tea and kicks back.> Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
trancexx Posted January 30, 2014 Share Posted January 30, 2014 Really? Are you trying to screw with peoples' heads on purpose? Logically NO, a pointer is not truly an array until either a. you know the context in which it appears, or b. you go ahead and treat it as one regardless (as you have done). The latter is just absurd and dangerous, and really the '[]' operator is only syntactic sugar that results in the operation "*(arr + n)". If you want to falsely assume that if you can apply [] to any pointer, that it is then by default an array, then you are dead wrong and will wind up writing shit code that crashes. Offset operator is dereference operator. Its full name is "offset dereference operator". Dereferencing any pointer, regardless of used notation is dangerous without the context. The two notations are interchangeable, for reasons already given. Therefore you can apply [] on any pointer to which * can be applied, with the same amount of risk. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Ascend4nt Posted January 30, 2014 Share Posted January 30, 2014 Offset operator is dereference operator. Its full name is "offset dereference operator". Dereferencing any pointer, regardless of used notation is dangerous without the context. The two notations are interchangeable, for reasons already given. I love it when you get technical But actually the standard defines the brackets operator as an array subscript operator. Oh snap! hehe.. but really as I said, its the same thing as *(arr + n) - just pointer math combined with the *cough* "indirection operator". Therefore you can apply [] on any pointer to which * can be applied, with the same amount of risk. I'd disagree with that, unless you most always use math with a dereference operator. tsk, indirection operator, that is. Its all good in the hood though My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
trancexx Posted January 30, 2014 Share Posted January 30, 2014 Anyone who would now say word "subscript" to prove me wrong is gay. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
trancexx Posted January 30, 2014 Share Posted January 30, 2014 It would be cooler if my post were just before yours. Right? ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Ascend4nt Posted January 30, 2014 Share Posted January 30, 2014 rofl My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Richard Robertson Posted January 31, 2014 Share Posted January 31, 2014 Offset operator is dereference operator. Its full name is "offset dereference operator". Dereferencing any pointer, regardless of used notation is dangerous without the context. The two notations are interchangeable, for reasons already given. Therefore you can apply [] on any pointer to which * can be applied, with the same amount of risk. Assuming it hasn't been overloaded explicitly. C++ was pretty lenient with operator overloading. Link to comment Share on other sites More sharing options...
Ascend4nt Posted January 31, 2014 Share Posted January 31, 2014 Assuming it hasn't been overloaded explicitly. C++ was pretty lenient with operator overloading. Dereference operators can't be overloaded for a pointer. You could overload them for an object that a pointer references, of course.. but even then you'd need to dereference the pointer first (*ptr)[n]. My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Richard Robertson Posted February 1, 2014 Share Posted February 1, 2014 Really? I was pretty sure you could overload pointer types too. I vaguely remember writing an operator that took a void* as an argument. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now