Re: [DNG] Making sense of C pointer syntax.
On Mon, 28 Mar 2016 13:57:08 -0300 Emiliano Marini wrote: > char *p; > p="01234"; /* skeezy, but makes the point */ > > Warning! Here "p" is pointing to nowhere, you don't know which memory > locations are writing to. Yeah, that's why I said "skeezy". But on some of compilers, you can actually strcpy(p, "43210") and you will neither get a compile time error nor a runtime one, because when p is in scope, it points to 6 bytes *somewhere*, even if on the stack. Also, if you *know* p will only be as an input and will not be changed, my syntax is OK, although a #define would be better. SteveT Steve Litt March 2016 featured book: Quit Joblessness: Start Your Own Business http://www.troubleshooters.com/startbiz ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] devuan installer main menu access
On Mon, Mar 28, 2016 at 06:30:42PM -0400, Boruch Baum wrote: > 4.1] Was it a case of 'fat-fingerng'? I don't think so, but it's asking > a lot to attempt to re-create this because with slow bandwidth, each > install attempt takes a long time to get to this stage. Today's > connection was especially slow. This has been the only time and point in > the install process that I've had a problem returning to the main menu, > so it might have been an errant keystroke, but I think I was being careful. You had previously indicated you have other debian/devuan boxes on your network. Is there any reason why you can't install apt-cacher-ng on one of them? You could then experiment with as many install attempts as you want without having to download the same packages all over again. Greg -- web site: http://www.gregn.net gpg public key: http://www.gregn.net/pubkey.asc skype: gregn1 (authorization required, add me to your contacts list first) If we haven't been in touch before, e-mail me before adding me to your contacts. -- Free domains: http://www.eu.org/ or mail dns-mana...@eu.org ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Exactly, to modify a pointer you need a pointer to that pointer. Remember in C, function parameters are "read only" because they're always copies of the calling variable's values. This is wrong: function abcd(void *p) { p = malloc(sizeof(int)); // Memory leaking *p = 1; } main () { int *p = malloc(sizeof(int)); // [1] *p = 0; abcd(p); // Sends a copy of the value of p // p is still pointing to memory reserved by [1], so *p equals 0 } This is OK: function abcd(void **p) { *p = malloc(sizeof(int)); **p = 1; } main() { int i = 0; int *p = &i; // p has the address where i is located // Here *p is 0 efgh(&p); // Sends a copy of the address where p is stored // Now p is pointing to some address in the heap segment, and *p is 1 } IMHO you need to be careful when allocating memory inside functions. In some cases it would be a good practice checking the value of the pointer before allocating (!null) to avoid memory leaking. However, if you look at this last example, p is pointing to local memory, and you can overwrite it's value safely (so checking if p is not null before allocating wouldn't be any help). But, if you call this function twice, you will leak memory: efgh(&p); // [1] efgh(&p); // Now you can't free the memory reserved at [1] Cheers, Emiliano. On Mon, Mar 28, 2016 at 4:55 PM, Edward Bartolo wrote: > Hi, > > Thanks for dedicating some of your time to answer me. I used: > > void change_value(void** ptr) > > Because I wanted to enable myself to allocate memory for the pointer > inside the function, therefore I needed a pointer to a pointer of type > void. Void allows such a function to handle different data types in > which case an ordinal typed parameter may be used to allow a switch > statement within the function to handle the different data types. I > used such a construct in Delphi Pascal in the past, and consider it a > powerful feature that can have its uses. This is why I am anxious to > comprehend the why behind pointer to pointer use. > > This is a program employing the use of a pointer to change the value > of a parameter inside a function. > > #include > #include > > int afunc(double* dd) { > *dd *= 2; > } > > int main() { > double* mm; > mm = malloc(sizeof(double)); > printf("value of mm after creation, unassigned: %f\n", *mm); > *mm = 1.0; > > int j; > for (j = 1; j <= 20; j++) { > afunc(mm); > printf("value of mm after function call %d: %f\n", j, *mm); > } > > free(mm); > > return 0; > } > > I will post tomorrow a reply illustrating the allocation of memory to > a pointer within a function. This means the function must be able to > modify the pointer not only its data. For that I will probably need a > pointer to a pointer or use typecasting with a standard data type > having the same number of bytes as a pointer. The reason for this is > the fact that a pointer is a number. > > I found using the return value of a function makes code much more > readable and probably more reliable. Multiple return values can be > encapsulated inside a structure which would be returned by a function. > I used this construct in simple-netaid-lightweight which avoids the > use of GtkBuilder. > > Edward > ___ > Dng mailing list > Dng@lists.dyne.org > https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng > ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
[DNG] devuan installer main menu access
Short version: From the screen that lets the user select specific system components to install, eg. XFCE, print server, SSH server, when I tabbed to the selection "go back" with the intention of getting the main menu, what happened instead was the installer began downloading "1173 packages". The only way I could figure to stop was to M-C-del, producing a SIGTERM which rebooted. Expanded version: 1] As a follow-up to a comment I made last week about saving downloaded components for future installs (saving bandwidth/time), I've been experimenting with how a user could re-use components using the ash shell that's available with the net installer. 2] The first set of downloads, for the installer's own components, seem to be deleted immediately upon their install. I was not able to retrieve them for re-use from ash. FAILURE 3] The second set of downloads, for the linux base system, may have been left on the target, but in advance of that download step, the debian install commands with which I am familiar were not available. I had archived deb files available to the installer and to the target, but got stuck at trying to perform something like 'apt-get update' to let the installer know they were there. FAILURE 4] The third set of downloads, for the additional system components, should have been the easy lift. What I did was deselect the options for a desktop and for a print server, expecting the system to want to download ~273 files, as it did on prior tests. At that point, I tried doing what I had no problem doing for the prior two stages - return to the main install menu, and open up a shell. I tabbed to 'go back', pressed 'enter', but the installer began downloading packages instead of presenting the main menu, and indicated that it would download 1173 packages instead of 273. 4.1] Was it a case of 'fat-fingerng'? I don't think so, but it's asking a lot to attempt to re-create this because with slow bandwidth, each install attempt takes a long time to get to this stage. Today's connection was especially slow. This has been the only time and point in the install process that I've had a problem returning to the main menu, so it might have been an errant keystroke, but I think I was being careful. 4.2] It would be nice to have had a less destructive method of aborting the download than to reboot. -- hkp://keys.gnupg.net CA45 09B5 5351 7C11 A9D1 7286 0036 9E45 1595 8BC0 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Hi, Thanks for dedicating some of your time to answer me. I used: void change_value(void** ptr) Because I wanted to enable myself to allocate memory for the pointer inside the function, therefore I needed a pointer to a pointer of type void. Void allows such a function to handle different data types in which case an ordinal typed parameter may be used to allow a switch statement within the function to handle the different data types. I used such a construct in Delphi Pascal in the past, and consider it a powerful feature that can have its uses. This is why I am anxious to comprehend the why behind pointer to pointer use. This is a program employing the use of a pointer to change the value of a parameter inside a function. #include #include int afunc(double* dd) { *dd *= 2; } int main() { double* mm; mm = malloc(sizeof(double)); printf("value of mm after creation, unassigned: %f\n", *mm); *mm = 1.0; int j; for (j = 1; j <= 20; j++) { afunc(mm); printf("value of mm after function call %d: %f\n", j, *mm); } free(mm); return 0; } I will post tomorrow a reply illustrating the allocation of memory to a pointer within a function. This means the function must be able to modify the pointer not only its data. For that I will probably need a pointer to a pointer or use typecasting with a standard data type having the same number of bytes as a pointer. The reason for this is the fact that a pointer is a number. I found using the return value of a function makes code much more readable and probably more reliable. Multiple return values can be encapsulated inside a structure which would be returned by a function. I used this construct in simple-netaid-lightweight which avoids the use of GtkBuilder. Edward ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Roger Leigh writes: > On 28/03/2016 15:35, Steve Litt wrote: >> On Mon, 28 Mar 2016 06:03:13 -0400 >> Boruch Baum wrote: >> >>> Why on this list, of all the possible places in Creation? It's a great >>> and important topic, but have you found no other, more appropriate >>> forum? > >> Because we're developing software. > > I'd have to say that while I'm mostly just an observer here, I do > consider this thread close to noise with precious little of value in > it. And complaints about the horror of having to ignore discussions about topics one isn't interested in have exactly no value. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
On 28/03/2016 15:35, Steve Litt wrote: On Mon, 28 Mar 2016 06:03:13 -0400 Boruch Baum wrote: Why on this list, of all the possible places in Creation? It's a great and important topic, but have you found no other, more appropriate forum? > Because we're developing software. I'd have to say that while I'm mostly just an observer here, I do consider this thread close to noise with precious little of value in it. While it's certainly true that the list is related to software development (or would that be better stated as distribution development, which is somewhat higher-level?), it's also true that there are plenty of more appropriate forums for basic and intermediate C questions, and also a vast wealth of books and other materials which cover it in great detail. Kind regards, Roger ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
k...@aspodata.se writes: > Rainer Weikusat: > ... >> One thing to note here: Every C pointer is really a pointer to an array >> of values, although the size of the array may just be one. > ... > > I thought it was the other way around, a pointer is just an address to > some (a single) memory location which can be part of an array, I'd > not consider int ii to be an array even though int *pp = &ii, > -- but who cares. What I was trying to get at was that C doesn't differentiate between 'pointer to object' and 'pointer to array of objects': Assuming that p is a valid pointer, the object pointed to by p can always be accessed both via *p and via p[0] and p + 1 will always be a valid pointer, too, either one pointing to the next element of the array if there are at least two elements or the 'just beyond the end' pointer guaranteed to be usable for size calculations via pointer subtractions. This is also true if the pointer was implicitly created by using an expression of array type for something other than "[...] the operand of the sizeof operator or the unary & operator, or [...] a string literal used to initialize an array" Eg, after the following array definition int a[] = {0, 1, 2}; *a is a valid expression for accessing the first element. > But there is a real differnce between > int arr[10]; > and > int *pp = calloc(10, sizeof(int)); > as pp can be assigned to, but not arr, i.e. pp = malloc() works > but not arr = malloc(). The pointer arr is converted to is not an lvalue. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
I was wrong because in this examples p was a pointer to int. Sorry, I was thinking on something like this: int *p; *p = 0; Cheers, Emiliano. On Mon, Mar 28, 2016 at 2:16 PM, Emiliano Marini wrote: > You're right. > > On Mon, Mar 28, 2016 at 2:04 PM, Rainer Weikusat < > rainerweiku...@virginmedia.com> wrote: > >> Emiliano Marini writes: >> > char *p; >> > p="01234"; /* skeezy, but makes the point */ >> > >> > Warning! Here "p" is pointing to nowhere, you don't know which memory >> > locations are writing to. >> >> The 'memory location' (if any) reserved for the pointer p itself by the >> compiler, IOW, this is totally correct. >> >> > >> > char *p; >> > *p=malloc...* >> > p="01234"; /* skeezy, but makes the point */ >> >> And this is a memory leak as the pointer returned by malloc is >> overwritten. >> ___ >> Dng mailing list >> Dng@lists.dyne.org >> https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng >> > > ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
You're right. On Mon, Mar 28, 2016 at 2:04 PM, Rainer Weikusat < rainerweiku...@virginmedia.com> wrote: > Emiliano Marini writes: > > char *p; > > p="01234"; /* skeezy, but makes the point */ > > > > Warning! Here "p" is pointing to nowhere, you don't know which memory > > locations are writing to. > > The 'memory location' (if any) reserved for the pointer p itself by the > compiler, IOW, this is totally correct. > > > > > char *p; > > *p=malloc...* > > p="01234"; /* skeezy, but makes the point */ > > And this is a memory leak as the pointer returned by malloc is > overwritten. > ___ > Dng mailing list > Dng@lists.dyne.org > https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng > ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
The main difference here is where you are storing the value "2000". In the first example, p is located in addresses belonging to "main" memory space (the stack presumably, beacuse "main" is the first function called upon start). You are passing the memory address of p (where p is located) to the function "change_value". The function assumes the memory address you are passing it's valid (meaning that it can be written safely). If you call "change_value" with null or with an invalid address (an address outside of all segments) you will cause a segfault. In the second example, "change_value" creates a new memory space (in the heap) to store "2000". This means you aren't "changing" anything. Every time you call "change_value" it creates a new """instance""" of "2000". Plus, if you don't free p before calling it again ("change_value(&p)"), you will be trashing memory (memory that cannot be released later, because you don't know their addresses). On Mon, Mar 28, 2016 at 3:50 AM, Edward Bartolo wrote: > Hi, > > As the title of the email indicates, I am doing some exercises to make > sense out of C pointer syntax. I have been using pointers for as long > as I have been programming without issues, apart from the usual > initial programmatic errors when new code is run for the first time. > However, C pointer syntax is proving to be as unintuitive as it can > be. For this reason, I am doing some exercises regarding C pointer > use. > > I am attaching two short C programs that I created and which I tested > to work although the mechanism by which they work is still somewhat > hazy to me. Both programs use a function to change the value of a > parameter. I want to understand, as opposed to knowing by rote, the > mechanism why they work. Please note that I didn't consult any books > to create the pointers. This is because I have already the concepts, > but I cannot make sense, as in deeply understanding the details, of > pointer syntax as used in C. > > Edward > > ___ > Dng mailing list > Dng@lists.dyne.org > https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng > > ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Emiliano Marini writes: > char *p; > p="01234"; /* skeezy, but makes the point */ > > Warning! Here "p" is pointing to nowhere, you don't know which memory > locations are writing to. The 'memory location' (if any) reserved for the pointer p itself by the compiler, IOW, this is totally correct. > > char *p; > *p=malloc...* > p="01234"; /* skeezy, but makes the point */ And this is a memory leak as the pointer returned by malloc is overwritten. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
char *p; p="01234"; /* skeezy, but makes the point */ Warning! Here "p" is pointing to nowhere, you don't know which memory locations are writing to. char *p; *p=malloc...* p="01234"; /* skeezy, but makes the point */ On Mon, Mar 28, 2016 at 12:59 PM, Steve Litt wrote: > On Mon, 28 Mar 2016 14:51:19 +0200 (CEST) > k...@aspodata.se wrote: > > > Rainer Weikusat: > > ... > > > One thing to note here: Every C pointer is really a pointer to an > > > array of values, although the size of the array may just be one. > > ... > > > > I thought it was the other way around, a pointer is just an address to > > some (a single) memory location which can be part of an array > > You're both right. A pointer is definitely an address of a single > memory address of a single byte or char or int or whatever, but that > single memory address *could* be the first element of an array, thus > defining the beginning location of the whole array. And of course the > end of the array must be defined by a second pointer, an integer > length, or a sentinel value such as '\0' or NULL. > > char *p; > p="01234"; /* skeezy, but makes the point */ > printf("p points to char %c\n", *p); > printf("p indicates start of string %s\n", p); > > > SteveT > > Steve Litt > March 2016 featured book: Quit Joblessness: Start Your Own Business > http://www.troubleshooters.com/startbiz > ___ > Dng mailing list > Dng@lists.dyne.org > https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng > ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Steve Litt: ... > Years ago I gave up trying to logically explain the syntax of function > pointers, which are so essential for callbacks and pseudo-oop, and just > memorized the idiom. > > Edition 1 of K&R had an actual algorithm by which one could dissect any > lvalue (thing that can appear on the left of the equal sign), but it > was so complicated I couldn't understand it. So I memorized the idiom > for function pointers. > > I think C would have been much more successful (and it's already been > quite successful) if it could have had a better syntax for function > pointers. Too late to change that, but I think you are better off if you do a typedef first, as in: typedef int (*func_t)(int,int); int add(int a, int b) { return a + b; } int proc(func_t f, int a, int b) { return f(a,b); } int main(void) { int ix = 0; func_t func_arr[10]; func_arr[0] = add; return proc(func_arr[ix], 1, 2); } $ gcc -Wall a.c $ ./a.out $ echo $? 3 > I think the reason you see so few callback functions in > average C code is the syntax, Just because c gives you the possibility to make code that looks like tty noise, doesn't mean you have to... > as well as the unforgivingly strict typing > of the arguments. ... The strict typing comes with the language, but you can get around it with pointers (gives you 0 to x number of arguments, same type unless the type is void). You can use varargs, and a remote possibility is to pass down a string and parse it which is quite radable from the calling side :) Regards, /Karl Hammar --- Aspö Data Lilla Aspö 148 S-742 94 Östhammar Sweden +46 173 140 57 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Hi Boruch, On 03/28/2016 02:00 PM, Boruch Baum wrote: Why on this list, of all the possible places in Creation? It's a great and important topic, but have you found no other, more appropriate forum? This is an appropiate list to argue about pointers. Have a look at the code of some projects like vdev or the backend of simple-netaid. Cheers, Aitor. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
On Mon, 28 Mar 2016 12:28:03 +0200 (CEST) k...@aspodata.se wrote: > To exemplify the "as they are used" statement, take a function > pointer declaration: > > void (*log_func)(int priority, const char *format); > > here you cannot conveniently move the "*" to the "void" so it will > look like a "pointer" declaration; it declares log_func to be > something which if used as (*log_func)(a, b, d) will "give" you a > void value. Years ago I gave up trying to logically explain the syntax of function pointers, which are so essential for callbacks and pseudo-oop, and just memorized the idiom. Edition 1 of K&R had an actual algorithm by which one could dissect any lvalue (thing that can appear on the left of the equal sign), but it was so complicated I couldn't understand it. So I memorized the idiom for function pointers. I think C would have been much more successful (and it's already been quite successful) if it could have had a better syntax for function pointers. I think the reason you see so few callback functions in average C code is the syntax, as well as the unforgivingly strict typing of the arguments. Some time compare what it takes to do a callback in C compared to Python, or especially Lua. SteveT Steve Litt March 2016 featured book: Quit Joblessness: Start Your Own Business http://www.troubleshooters.com/startbiz ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
On Mon, 28 Mar 2016 14:51:19 +0200 (CEST) k...@aspodata.se wrote: > Rainer Weikusat: > ... > > One thing to note here: Every C pointer is really a pointer to an > > array of values, although the size of the array may just be one. > ... > > I thought it was the other way around, a pointer is just an address to > some (a single) memory location which can be part of an array You're both right. A pointer is definitely an address of a single memory address of a single byte or char or int or whatever, but that single memory address *could* be the first element of an array, thus defining the beginning location of the whole array. And of course the end of the array must be defined by a second pointer, an integer length, or a sentinel value such as '\0' or NULL. char *p; p="01234"; /* skeezy, but makes the point */ printf("p points to char %c\n", *p); printf("p indicates start of string %s\n", p); SteveT Steve Litt March 2016 featured book: Quit Joblessness: Start Your Own Business http://www.troubleshooters.com/startbiz ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Because we're developing software. On Mon, 28 Mar 2016 06:03:13 -0400 Boruch Baum wrote: > Why on this list, of all the possible places in Creation? It's a great > and important topic, but have you found no other, more appropriate > forum? > > On 03/28/2016 02:50 AM, Edward Bartolo wrote: > > Hi, > > > > As the title of the email indicates, I am doing some exercises to > > make sense out of C pointer syntax. I have been using pointers for > > as long as I have been programming without issues, apart from the > > usual initial programmatic errors when new code is run for the > > first time. However, C pointer syntax is proving to be as > > unintuitive as it can be. For this reason, I am doing some > > exercises regarding C pointer use. > > > > I am attaching two short C programs that I created and which I > > tested to work although the mechanism by which they work is still > > somewhat hazy to me. Both programs use a function to change the > > value of a parameter. I want to understand, as opposed to knowing > > by rote, the mechanism why they work. Please note that I didn't > > consult any books to create the pointers. This is because I have > > already the concepts, but I cannot make sense, as in deeply > > understanding the details, of pointer syntax as used in C. > > > > Edward ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Rainer Weikusat: > k...@aspodata.se writes: ... > > With pointers, you have to handle the special case of null pointers. > > I'm assuming you are omitting it here for brevity, but generally > > change_value() should be something like: > > > > void change_value(int* ptr) { > > if (!ptr) return; > > *ptr = 2000; > > } > > It absolutely shouldn't unless NULL is expected to be valid, used > argument value for some reason. If not, code passing NULL to such a > function is likely erroneous. Forcing the program to abort, preferably > with a core dump, via SIGSEGV will often enable fixing the error easily > and quick. Silently bouncing it out of the function again so that it > further propagates through the program is a terribly risky practice with > literally unpredictable consequences. Ok, I see your point (I'm used to functions that do error logging and error returns, maybe if(!ptr) abort() would suit you better, but that would incur non productive overhead, even though it better states what happens for this special case). But are you saying that the def. func(int * pp) says that null's are not allowed unless specifically allowed ? I somehow regards pp in func(int * pp) to be whatever you can put into an int*, no exceptions, and func() has to be able to handle the heat. For the actual function change_value(), what is the semantics to changing something that doesn't exist ? It could be abort() but it could just as well be just a no-op, choose your pick. You can compare it to the array case for (ix = 0; ix < arr_max; ix++) { change_value(arr + ix); } If the array is empty, that would be a big no-op. Or would you choose an abort() when arr_max == 0 ? /// But we can agree on that you have to be careful about null pointers. Regards, /Karl Hammar --- Aspö Data Lilla Aspö 148 S-742 94 Östhammar Sweden +46 173 140 57 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Rainer Weikusat: > k...@aspodata.se writes: ... > > To exemplify the "as they are used" statement, take a function pointer > > declaration: > > > > void (*log_func)(int priority, const char *format); > > > > here you cannot conveniently move the "*" to the "void" so it will look > > like a "pointer" declaration; it declares log_func to be something which > > if used as (*log_func)(a, b, d) will "give" you a void value. > > Unless something more interesting is being done, function pointers don't > need to be dereferenced, they can be used just like functions. ... You need it in the declaration, but not in the use, but I didn't want to confuse the matter. Regards, /Karl Hammar --- Aspö Data Lilla Aspö 148 S-742 94 Östhammar Sweden +46 173 140 57 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Rainer Weikusat: ... > One thing to note here: Every C pointer is really a pointer to an array > of values, although the size of the array may just be one. ... I thought it was the other way around, a pointer is just an address to some (a single) memory location which can be part of an array, I'd not consider int ii to be an array even though int *pp = &ii, -- but who cares. But there is a real differnce between int arr[10]; and int *pp = calloc(10, sizeof(int)); as pp can be assigned to, but not arr, i.e. pp = malloc() works but not arr = malloc(). Regards, /Karl Hammar --- Aspö Data Lilla Aspö 148 S-742 94 Östhammar Sweden +46 173 140 57 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
k...@aspodata.se writes: [...] > With pointers, you have to handle the special case of null pointers. > I'm assuming you are omitting it here for brevity, but generally > change_value() should be something like: > > void change_value(int* ptr) { > if (!ptr) return; > *ptr = 2000; > } It absolutely shouldn't unless NULL is expected to be valid, used argument value for some reason. If not, code passing NULL to such a function is likely erroneous. Forcing the program to abort, preferably with a core dump, via SIGSEGV will often enable fixing the error easily and quick. Silently bouncing it out of the function again so that it further propagates through the program is a terribly risky practice with literally unpredictable consequences. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Edward Bartolo: ... > I am attaching two short C programs that I created and which I tested > to work although the mechanism by which they work is still somewhat > hazy to me. ... Some comments on test101.c #include void change_value(void* ptr) { *((int*) ptr) = 2000; } int main() { int p = 8; printf("p = %d\n", p); change_value(&p); printf("p = %d\n", p); return 0; } The definition "void change_value(void* ptr);" doesn't preclude the use double dd; change_value(&dd); You don't handle things other than int's, so don't invite the user of change_value() to use anything else, why the "void *ptr" (it only gives you headaches with casts) ? You'd be better off writing it as: void change_value(int* ptr) { *ptr = 2000; } Don't use single letter variables unless you have a as short scope as you have in your main(). Using pp instead of p makes it much easier to find in a simple editor or with grep, or with your own eyes. With pointers, you have to handle the special case of null pointers. I'm assuming you are omitting it here for brevity, but generally change_value() should be something like: void change_value(int* ptr) { if (!ptr) return; *ptr = 2000; } since the func. is defined as "void change_value(int* ptr);", and generally, users shouldn't be required to read the function body to realize that the null pointer is forbidden. /// Some comments on test102.c === #include #include void change_value(void** ptr) { int* i = (int*) malloc(sizeof(int)); *i = 10001002; *ptr = i; } int main() { int* p; //printf("p = %d\n", p); change_value((void**) &p); printf("p = %d\n", *p); free(p); return 0; } === Same comments as for test101.c, plus: If you use void change_value(int ** ptr) {} instead, your call in main() will simplify to change_value(&p); /* instead of change_value((void**) &p); */ as you don't need the cast any longer (you didn't need it for the void case either, but your compiler might have complained). It will also simplify (ignoring null pointers for the moment) the body to void change_value(int ** ptr) { * ptr = (int *) malloc(sizeof(int)); ** ptr = 10001002; } malloc() inside a function and free() outside it invites to memory leaks, don't do that to yourself. Something like void *mem = malloc(...); func_call(...); free(mem); is way more easy to debug. Yes, that doesn't map wery good to your example, but you might benefit from rethinking how you use malloc/free. /// Regards, /Karl Hammar --- Aspö Data Lilla Aspö 148 S-742 94 Östhammar Sweden +46 173 140 57 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
k...@aspodata.se writes: [...] > To exemplify the "as they are used" statement, take a function pointer > declaration: > > void (*log_func)(int priority, const char *format); > > here you cannot conveniently move the "*" to the "void" so it will look > like a "pointer" declaration; it declares log_func to be something which > if used as (*log_func)(a, b, d) will "give" you a void value. Unless something more interesting is being done, function pointers don't need to be dereferenced, they can be used just like functions. And vice-versa. Eg, this useless little program converts all its arguments to ints and prints a message stating if they were odd or even twice: --- #include #include static void even(int d) { printf("%d is even\n", d); } static void odd(int d) { printf("%d is odd\n", d); } static void (*f[])(int) = { even, odd }; int main(int argc, char **argv) { int i; while (*++argv) { i = atoi(*argv); /* function name used as expression turns into function pointer */ (i & 1 ? odd : even)(i); /* function pointer can be used like function */ f[i & 1](i); } return 0; } -- ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Edward Bartolo writes: > As the title of the email indicates, I am doing some exercises to make > sense out of C pointer syntax. I have been using pointers for as long > as I have been programming without issues, apart from the usual > initial programmatic errors when new code is run for the first time. > However, C pointer syntax is proving to be as unintuitive as it can > be. For this reason, I am doing some exercises regarding C pointer > use. [...] > #include > > void change_value(void* ptr) { > *((int*) ptr) = 2000; > } You could have declared that as int *ptr in order to get rid of the cast. Also, the precedence is such that *(int *)p = 2000; would work. [...] > #include > #include > > void change_value(void** ptr) { This is a somewhat dubious construct as every pointer is required to be convertible from and to void * but not void **. > int* i = (int*) malloc(sizeof(int)); The cast is not necessary. And you don't really need the intermediate pointer. --- #include #include void change_value(int **ptr) { *ptr = malloc(sizeof(**ptr)); **ptr = 10001002; } int main() { int* p; change_value(&p); printf("p = %d\n", *p); free(p); return 0; } -- This becomes much less arcane-looking when letting go of the Pascal-y 'bad habit' of using pass-by-reference to create procedure returning values. -- #include #include int *array_1(void) { int *pi; pi = malloc(sizeof(*pi)); *pi = 10001002; return pi; } int main() { int* p; p = array_1(); printf("p = %d\n", *p); free(p); return 0; } -- One thing to note here: Every C pointer is really a pointer to an array of values, although the size of the array may just be one. Given the above, both *p and p[0] are equally legitimate ways to access the value. As per C definition, p[0] can also be written as 0[p] or *(p + 0) the same being true for any other valid (not out-of-bounds) index. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Edward Bartolo: ... > However, C pointer syntax is proving to be as unintuitive as it can > be. ... > I want to understand, as opposed to knowing by rote, the > mechanism why they work. ... /// I think one source of confusion re. c-pointers is that they are declared "as they are used", but you migth not use them like that. If you take int *ix; then *ix will be an int, and you can _deduce_ that ix is a pointer to an int, but you don't say that directly. In your code you try to avoid the issue by writing "int* i;" and treating "int*" to be a "pointer" declaration. But "int * i ;" is four tokens regardless how you write it, you could just as well have written it as "int*i;" or "int *i;", same thing. To exemplify the "as they are used" statement, take a function pointer declaration: void (*log_func)(int priority, const char *format); here you cannot conveniently move the "*" to the "void" so it will look like a "pointer" declaration; it declares log_func to be something which if used as (*log_func)(a, b, d) will "give" you a void value. /// There is also a visual mismatch in c with a declaration of a pointer with an initializer. Example: int *ix = (int *) malloc(sizeof(int)); This line is the same thing as int *ix; /* i.e. *ix is an int */ ix = (int *) malloc(sizeof(int)); /* look no "*" */ So, int *ix = value; says two things; a: it declares an "ix" such as when ix is used as "*ix" it will be an int b: ix = value Another example is: #include #include void (*log_vfunc)(int priority, const char *format, va_list ap) = vsyslog; where the last line is the same thing as: void (*log_vfunc)(int priority, const char *format, va_list ap); log_vfunc = vsyslog; Regards, /Karl Hammar --- Aspö Data Lilla Aspö 148 S-742 94 Östhammar Sweden +46 173 140 57 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Making sense of C pointer syntax.
Why on this list, of all the possible places in Creation? It's a great and important topic, but have you found no other, more appropriate forum? On 03/28/2016 02:50 AM, Edward Bartolo wrote: > Hi, > > As the title of the email indicates, I am doing some exercises to make > sense out of C pointer syntax. I have been using pointers for as long > as I have been programming without issues, apart from the usual > initial programmatic errors when new code is run for the first time. > However, C pointer syntax is proving to be as unintuitive as it can > be. For this reason, I am doing some exercises regarding C pointer > use. > > I am attaching two short C programs that I created and which I tested > to work although the mechanism by which they work is still somewhat > hazy to me. Both programs use a function to change the value of a > parameter. I want to understand, as opposed to knowing by rote, the > mechanism why they work. Please note that I didn't consult any books > to create the pointers. This is because I have already the concepts, > but I cannot make sense, as in deeply understanding the details, of > pointer syntax as used in C. > > Edward > > > > ___ > Dng mailing list > Dng@lists.dyne.org > https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng > -- hkp://keys.gnupg.net CA45 09B5 5351 7C11 A9D1 7286 0036 9E45 1595 8BC0 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng