Re: [DNG] Making sense of C pointer syntax.

2016-05-26 Thread Edward Bartolo
Hi,

Thanks for the feedback. I applied the suggested changes to Makefile
and git push-ed to repository. There is still a non-fatal error about
linking against unnecessary libraries that has to be debugged. I will
git push as soon as I find a solution.

Edward

On 25/05/2016, aitor_czr  wrote:
>
> El 25/05/16 a las 10:50, aitor_czr escribió:
>> Hi Edward,
>>
>> El 29/03/16 a las 00:58, Edward Bartolo  escribió:
>>> 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
>>
>> Building your simple-netaid-lightweight, this is what i get:
>>
>>
>> aitor@localhost:~/simple-netaid-lightweight$ make
>> rm -f sn-lightweight
>> gcc -Iinclude `pkg-config --libs --cflags gtk+-2.0` -c
>> src/auxiliaries.c src/signal_functions.c src/main_gui.c
>> src/dialog_gui.c rc/sn-lightweight.c
>> mv *.o obj/
>> mv: el objetivo «obj/» no es un directorio
>> Makefile:16: recipe for target 'compile-objs' failed
>> make: *** [compile-objs] Error 1
>>
>>
>>
>> So, you need to modify the Makefile to something like this:
>>
>> CC=gcc
>> CFLAGS=-Iinclude
>> GTK2FLAGS=`pkg-config --libs --cflags gtk+-2.0`
>> D=src
>> OBJ=obj
>>
>> src0=auxiliaries.c signal_functions.c main_gui.c
>> src1=dialog_gui.c sn-lightweight.c
>>
>> SOURCEFILES=$(addprefix $(D)/, $(src0) $(src1))
>> OBJFILES=$(addprefix $(OBJ)/, $(src0:.c=.o) $(src1:.c=.o))
>>
>> all: clean compile-objs sn-lightweight
>>
>> compile-objs:
>> $(CC) $(CFLAGS) $(GTK2FLAGS) -c $(SOURCEFILES)
>> mkdir obj
>> mv *.o obj/
>>
>> sn-lightweight:
>> $(CC) $(CFLAGS) $(GTK2FLAGS) -o sn-lightweight $(OBJFILES)
>>
>> clean:
>> rm -f sn-lightweight
>>
>> After doing this change, it works :)
>>
>> Cheers,
>>
>>   Aitor.
>>
>> [*] Added "mkdir obj" line.
>>
>
> You must also include:
>
> rm -rf obj
>
> at the end of the Makefile.
>
>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.

2016-05-25 Thread aitor_czr


Hi Edward,

El 29/03/16 a las 00:58, Edward Bartolo  escribió:

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


Building your simple-netaid-lightweight, this is what i get:


aitor@localhost:~/simple-netaid-lightweight$ make
rm -f sn-lightweight
gcc -Iinclude `pkg-config --libs --cflags gtk+-2.0` -c src/auxiliaries.c 
src/signal_functions.c src/main_gui.c src/dialog_gui.c rc/sn-lightweight.c

mv *.o obj/
mv: el objetivo «obj/» no es un directorio
Makefile:16: recipe for target 'compile-objs' failed
make: *** [compile-objs] Error 1



So, you need to modify the Makefile to something like this:

CC=gcc
CFLAGS=-Iinclude
GTK2FLAGS=`pkg-config --libs --cflags gtk+-2.0`
D=src
OBJ=obj

src0=auxiliaries.c signal_functions.c main_gui.c
src1=dialog_gui.c sn-lightweight.c

SOURCEFILES=$(addprefix $(D)/, $(src0) $(src1))
OBJFILES=$(addprefix $(OBJ)/, $(src0:.c=.o) $(src1:.c=.o))

all: clean compile-objs sn-lightweight

compile-objs:
$(CC) $(CFLAGS) $(GTK2FLAGS) -c $(SOURCEFILES)
mkdir obj
mv *.o obj/

sn-lightweight:
$(CC) $(CFLAGS) $(GTK2FLAGS) -o sn-lightweight $(OBJFILES)

clean:
rm -f sn-lightweight

After doing this change, it works :)

Cheers,

  Aitor.

[*] Added "mkdir obj" line.



___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-04-15 Thread Edward Bartolo
Hi,

Again, thanks for taking some of your time to explain this to me.
Sorry for not replying immediately. The past two weeks I couldn't use
any of my computers.

Edward

On 03/04/2016, KatolaZ  wrote:
> On Sat, Apr 02, 2016 at 02:30:24PM -0400, Steve Litt wrote:
>
> [cut]
>
>>
>> > You never return a
>> > pointer to an automatic variable,
>>
>> How'd you learn that? I learned that by this particular incident, and I
>> *NEVER* did that again.
>>
>
> The answer to your question is always the same: I think I learnt it by
> reading "The Only Book You'll Ever Need About C", alas K second
> edition, once upon a time.
>
> HND
>
> KatolaZ
>
> --
> [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
> [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
> [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
> [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
> ___
> 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.

2016-04-03 Thread KatolaZ
On Sat, Apr 02, 2016 at 02:30:24PM -0400, Steve Litt wrote:

[cut]

> 
> > You never return a
> > pointer to an automatic variable, 
> 
> How'd you learn that? I learned that by this particular incident, and I
> *NEVER* did that again.
> 

The answer to your question is always the same: I think I learnt it by
reading "The Only Book You'll Ever Need About C", alas K second
edition, once upon a time.

HND

KatolaZ

-- 
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-04-02 Thread Rainer Weikusat
aitor_czr  writes:

> On 03/31/16 16:07, KatolaZ wrote:
>> On Thu, Mar 31, 2016 at 03:58:49PM +0200, aitor_czr wrote:
>>
>> [cut]
>>
 > >On Wed, Mar 30, 2016 at 6:04 PM, Rainer Weikusat <
 > >rainerweiku...@virginmedia.com> wrote:
 > >
 > >There's one
> > >>important difference:
> > >>
> > >>char chars[] = "12345";
> > >>
> > >>cause the compiler to reserve six bytes (five chars + terminating 0) 
> > >>in
> > >>some location the program can write to. Afterwards,
> > >>
> > >>*chars = R;
> > >>
> > >>could be used to change the string to R2345.
>>> >
>>> >This is because
>>> >
>>> >*chars  <--->  *(chars+0)  <--->  chars[0]
>>> >
>>> >are analogous. So, chars[0] changes from 1 to R.
>>> >
>> Again. being pedantic here the assignment:
>>
>>*chars = R;
>>
>> assigns the value of the variable R (which should be a char) to the
>> first byte of the memory area pointed by chars.

Considering what it was supposed to mean, it should have been obvious
that I forgot the quotes. Had R been a variable, its type could have
been any numerical type as the value is to be converted as required (in
fact, the type of 'R' is int, not char).

Some people think this is a useful convenience feature. Others are
convinced that that's a sign of tthe devil's agents being secretly at work to
deprave mankind and an eternity of purgatory among dysfunctional
computer must invariably ... hold a sec ... that already
happened. Despite the "other's opinion" is generally accepted. Hmm ...


#include 

char chars[] = "12345";

int main(void)
{
double R = 82.34;
0[chars] = R;
puts(chars);
return 0;
}


Turned into a program which can be compiled to avoid accidental syntax
errors this time.
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-04-02 Thread Hendrik Boom
On Sat, Apr 02, 2016 at 10:55:53AM +0100, KatolaZ wrote:
> On Fri, Apr 01, 2016 at 07:34:02PM -0400, Steve Litt wrote:
> 
> [cut]
> 
> > 
> > 
> > =
> > char * read_bbs(){
> >   char rtrn[WAY_BIGGER_THAN_EVER_NEEDED];
> >   strcpy(rtrn, grab_bbs_part1());
> >   strcat(rtrn, grab_bbs_part2());
> >   return(rtrn);
> > }
> > 
> > result_string = read_bbs();
> > do_other_stuff();
> > use_result_string(result_string);
> > =
> > 
> > Well, it worked 99.6% of the time, but once in a while the whole
> > program blew up. :-). I solved this intermittent on my third visit,
> > racked up probably 10 hours trying to fix it, and my problem probably
> > cost a couple hundred hours of keypuncher time before I fixed it.
> > 
> > WAY_BIGGER_THAN_EVER_NEEDED really was way bigger than ever needed. Bad
> > programming, but that wasn't the problem.
> > 
> > All I can say is I *never* made that mistake again.
> > 
> 
> Well, that one is a completely different beast... You never return a
> pointer to an automatic variable, unless it has been declared
> "static", for the simple reason that the variable does not exist any
> more when the function returns. Your code probably "worked" only
> because there was no call to any other functions in between (and thus
> the stack was magically unmodified), but otherwise that code should in
> general blow up pretty early, whatever the size of
> WAY_BIGGER_THAN_EVER_NEEDED...

The bigger WAY_BIGGER... is the lss often it would be likely to fail.  
If the stack grows in the directio of lower memory addresses, the 
beginning of rtrn would be farther from the caller's stack position, 
and thus less likely to be overrun by other function calls.

But it's still wrong.

-- hendrik
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-04-02 Thread KatolaZ
On Fri, Apr 01, 2016 at 07:34:02PM -0400, Steve Litt wrote:

[cut]

> 
> 
> =
> char * read_bbs(){
>   char rtrn[WAY_BIGGER_THAN_EVER_NEEDED];
>   strcpy(rtrn, grab_bbs_part1());
>   strcat(rtrn, grab_bbs_part2());
>   return(rtrn);
> }
> 
> result_string = read_bbs();
> do_other_stuff();
> use_result_string(result_string);
> =
> 
> Well, it worked 99.6% of the time, but once in a while the whole
> program blew up. :-). I solved this intermittent on my third visit,
> racked up probably 10 hours trying to fix it, and my problem probably
> cost a couple hundred hours of keypuncher time before I fixed it.
> 
> WAY_BIGGER_THAN_EVER_NEEDED really was way bigger than ever needed. Bad
> programming, but that wasn't the problem.
> 
> All I can say is I *never* made that mistake again.
> 

Well, that one is a completely different beast... You never return a
pointer to an automatic variable, unless it has been declared
"static", for the simple reason that the variable does not exist any
more when the function returns. Your code probably "worked" only
because there was no call to any other functions in between (and thus
the stack was magically unmodified), but otherwise that code should in
general blow up pretty early, whatever the size of
WAY_BIGGER_THAN_EVER_NEEDED...

Actually, returning a pointer to a local (automatic) static array is
exactly what some implementations of standard functions like "strtok"
do, and it works perfectly if you don't have multiple threads using
the same function.  But you should know exactly what you are doing...

My2Cents

KatolaZ

-- 
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-04-01 Thread Steve Litt
On Thu, 31 Mar 2016 13:53:08 +0100
KatolaZ  wrote:

 
> But be careful with statically initialised strings,
> since they are effectively constant char pointers (they are stored in
> the current stack frame, not in the heap, and the address stored in
> such variables cannot be modified, AFAIR).

This isn't exactly responsive to what you said, KatolaZ, but the worst
(and one of the most costly) programming mistakes I ever made was this:


=
char * read_bbs(){
  char rtrn[WAY_BIGGER_THAN_EVER_NEEDED];
  strcpy(rtrn, grab_bbs_part1());
  strcat(rtrn, grab_bbs_part2());
  return(rtrn);
}

result_string = read_bbs();
do_other_stuff();
use_result_string(result_string);
=

Well, it worked 99.6% of the time, but once in a while the whole
program blew up. :-). I solved this intermittent on my third visit,
racked up probably 10 hours trying to fix it, and my problem probably
cost a couple hundred hours of keypuncher time before I fixed it.

WAY_BIGGER_THAN_EVER_NEEDED really was way bigger than ever needed. Bad
programming, but that wasn't the problem.

All I can say is I *never* made that mistake again.

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.

2016-03-31 Thread Hendrik Boom
On Thu, Mar 31, 2016 at 03:58:49PM +0200, aitor_czr wrote:
> Hi,
> 
> On 03/31/16 13:38, Emiliano Marini  wrote:
> >Besides, * and [] are interchangeable. You can define a string as an array
> >and use it later as a pointer:
> >
> >char s[] = "hola";
> >char x = s[1]; // Here x = 'o'
> >char y = *(s+2);   // Here y = 'l'
> >
> >And vice versa:
> >
> >char *s = "hola";
> >char x = s[0]; // Here x = 'h'
> >char y = *(s+3);   // Here y = 'a'
> 
> This is right, and the following sintax are analogous:
> 
>  *(p+i) <--->  p[i]

In fact, in the original C specification, p[i] was *defined* to mean *(p+i).

-- hendrik
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-31 Thread Hendrik Boom
On Thu, Mar 31, 2016 at 03:18:17PM +0100, KatolaZ wrote:
> On Thu, Mar 31, 2016 at 03:12:32PM +0200, Edward Bartolo wrote:
> > Hi, thanks for taking time to reply,
> > 
> > KatolaZ wrote:
> > >> c) type **ss; // declare a pointer to pointer. System only allocates
> > >> space for one address
> > 
> > > C pointers are *always* one variable, precisely a variable large
> > > enough to store a memory address on the current architecture.
> > 
> > I think, I did not understand what you want to say. As far as I can
> > imagine a pointer to pointer is something like this:
> > [pointer1]-->[pointer2]--->[data]  int the case of data** dt.
> > 
> > OR
> > 
> > [pointer1]-->[pointer2] in the case of void** ptr.
> > 

Your example would be correct *only if* and pointer1, pointer2 
actually contained proper addresses of memory instead of containing 
uninitialized junk or NULL.

And that, I think, is what KatolaZ is tryng to point out.
> 
> Nope. This is totally wrong. What you have in memory after a
> declaration:
> 
>   type *a;
> 
> is just *one variable*, namely a variable able to contain a memory
> address.

Yes.  It is only when you actually assgn a pointer to a that your 
   pointer->data

diagram becomes valied.

-- hendrik

> When you declare:
> 
>   type **b;
> 
> you still have exactly *one variable* allocated in memory, namely one
> variable able to contain a memory address, and not *two variables* as
> in your example above.  This does not depend on what "type" is, so
> each of the following declarations:
> 
>  int  *a;
>  double ***b;
>  void c;
>  myowntype **d;
> 
> will result in the allocation of exactly *one variable*, namely a
> variable large enough to contain a pointer (i.e., a memory address). I
> don't want to confuse you, but in my example myowntype might also be
> declared as:
> 
>   typedef char*** myowntype;
> 
> and still the declaration:
> 
>   myowntype **d;
> 
> will reserve exactly one variable in memory, namely a variable large
> enough to contain a memory address.
> 
> The declaration is used only by the compiler to understand what is the
> implicit semantic of the pointer arithmetic to be used with that
> pointer, and to check that you are not palying nastly with it, so that
> 
>   int *p;
>   ...
>   p += 1;
> 
> assigns to p the address of the memory location which is 1*sizeof(int)
> bytes after the old address stored into p, while:
> 
>   double *p;
>   ...
>   p +=2;
> 
> will assign to p the address of the memory location which is
> 2*sizeof(double) bytes after the old address stored in p. 
> 
> You have not broken the pointers spell, yet. I warmly suggst you to
> read a good introduction to C pointers, but the only thing that comes
> to my mind is the Kernighan and Ritchie, which I admit is not the
> easiest book around (although it is certainly the best on the
> subject).
> 
> My2Cents
> 
> KatolaZ
> 
> -- 
> [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
> [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
> [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
> [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
> ___
> 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.

2016-03-31 Thread aitor_czr

On 03/31/16 16:07, KatolaZ wrote:

On Thu, Mar 31, 2016 at 03:58:49PM +0200, aitor_czr wrote:

[cut]


> >On Wed, Mar 30, 2016 at 6:04 PM, Rainer Weikusat <
> >rainerweiku...@virginmedia.com> wrote:
> >
> >There's one

> >>important difference:
> >>
> >>char chars[] = "12345";
> >>
> >>cause the compiler to reserve six bytes (five chars + terminating 0) in
> >>some location the program can write to. Afterwards,
> >>
> >>*chars = R;
> >>
> >>could be used to change the string to R2345.

>
>This is because
>
>*chars  <--->  *(chars+0)  <--->  chars[0]
>
>are analogous. So, chars[0] changes from 1 to R.
>

Again. being pedantic here the assignment:

   *chars = R;

assigns the value of the variable R (which should be a char) to the
first byte of the memory area pointed by chars. If you we want to
change the first character of the string into the letter 'R', we
should write:

   *chars = 'R';

Notice the (sometimes misleading and) subtle difference between single
quotes ('), which are used for character constants, and double quotes
(") which are used to delimit strings (i.e., they are the syntactic
sugar around constant arrays of char).

My2Cents

KatolaZ


Uppps :)
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-31 Thread karl
Edward Bartolo:
> KatolaZ wrote:
> >> c) type **ss; // declare a pointer to pointer. System only allocates
> >> space for one address
> 
> > C pointers are *always* one variable, precisely a variable large
> > enough to store a memory address on the current architecture.
> 
> I think, I did not understand what you want to say. As far as I can
> imagine a pointer to pointer is something like this:
> [pointer1]-->[pointer2]--->[data]  int the case of data** dt.
...

To be picky, "int ** id;", just defines an allocates one variable id
that when used like **id will have the type int. It says nothing about
what value id, *id, **id will have, nor if *id or **id will be in any
way useful.

For **id be useful *id has to have some defined value, e.g.

int main(void) {
  int  data = 4;
  int * pointer1 = & data;
  int ** pointer2 = & pointer1;
  int *** pointer3 = & pointer2;
  int  pointer4 = & pointer3;
  /* etc... */
  return  pointer4;
}

$ gcc -Wall a.c; ./a.out; echo $?
4

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.

2016-03-31 Thread KatolaZ
On Thu, Mar 31, 2016 at 03:58:49PM +0200, aitor_czr wrote:

[cut]

> >On Wed, Mar 30, 2016 at 6:04 PM, Rainer Weikusat <
> >rainerweiku...@virginmedia.com> wrote:
> >
> >There's one
> >>important difference:
> >>
> >>char chars[] = "12345";
> >>
> >>cause the compiler to reserve six bytes (five chars + terminating 0) in
> >>some location the program can write to. Afterwards,
> >>
> >>*chars = R;
> >>
> >>could be used to change the string to R2345.
> 
> This is because
> 
> *chars  <--->  *(chars+0)  <--->  chars[0]
> 
> are analogous. So, chars[0] changes from 1 to R.
> 

Again. being pedantic here the assignment:

  *chars = R;

assigns the value of the variable R (which should be a char) to the
first byte of the memory area pointed by chars. If you we want to
change the first character of the string into the letter 'R', we
should write:

  *chars = 'R';

Notice the (sometimes misleading and) subtle difference between single
quotes ('), which are used for character constants, and double quotes
(") which are used to delimit strings (i.e., they are the syntactic
sugar around constant arrays of char).

My2Cents

KatolaZ

-- 
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-31 Thread aitor_czr

Hi,

On 03/31/16 13:38, Emiliano Marini  wrote:

Besides, * and [] are interchangeable. You can define a string as an array
and use it later as a pointer:

char s[] = "hola";
char x = s[1]; // Here x = 'o'
char y = *(s+2);   // Here y = 'l'

And vice versa:

char *s = "hola";
char x = s[0]; // Here x = 'h'
char y = *(s+3);   // Here y = 'a'


This is right, and the following sintax are analogous:

 *(p+i) <--->  p[i]

*(*(p+i)+j) <--->  p[i][j]

This last one in the case of a double pointer.


On Wed, Mar 30, 2016 at 6:04 PM, Rainer Weikusat <
rainerweiku...@virginmedia.com> wrote:

There's one
>important difference:
>
>char chars[] = "12345";
>
>cause the compiler to reserve six bytes (five chars + terminating 0) in
>some location the program can write to. Afterwards,
>
>*chars = R;
>
>could be used to change the string to R2345.


This is because

*chars  <--->  *(chars+0)  <--->  chars[0]

are analogous. So, chars[0] changes from 1 to R.

  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.

2016-03-31 Thread Edward Bartolo
Hi, thanks for taking time to reply,

KatolaZ wrote:
>> c) type **ss; // declare a pointer to pointer. System only allocates
>> space for one address

> C pointers are *always* one variable, precisely a variable large
> enough to store a memory address on the current architecture.

I think, I did not understand what you want to say. As far as I can
imagine a pointer to pointer is something like this:
[pointer1]-->[pointer2]--->[data]  int the case of data** dt.

OR

[pointer1]-->[pointer2] in the case of void** ptr.

Edward

On 31/03/2016, KatolaZ  wrote:
> On Thu, Mar 31, 2016 at 08:38:26AM -0300, Emiliano Marini wrote:
>> +1
>>
>> Besides, * and [] are interchangeable. You can define a string as an array
>> and use it later as a pointer:
>>
>> char s[] = "hola";
>> char x = s[1]; // Here x = 'o'
>> char y = *(s+2);   // Here y = 'l'
>>
>> And vice versa:
>>
>> char *s = "hola";
>> char x = s[0]; // Here x = 'h'
>> char y = *(s+3);   // Here y = 'a'
>>
>
> Just to be pedantic here, "[]" is just syntactic sugar around the
> dereference operator "*". And in fact "[]" did not even exist in the
> first versions of proto-C. Obviously, "[]" is syntactic sugar around
> unary "*" for *any* kind of pointer, not just for strings.
>
> Also, initialisation of char* and char[] by means of
>
>   char s[] = "hello";
>
> is syntactic sugar around the generic initialiser:
>
>   type p = {...};
>
> which allows to initialise arrays and compound variables (structs and
> unions) as well. But be careful with statically initialised strings,
> since they are effectively constant char pointers (they are stored in
> the current stack frame, not in the heap, and the address stored in
> such variables cannot be modified, AFAIR).
>
> My2Cents
>
> KatolaZ
>
> --
> [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
> [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
> [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
> [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
> ___
> 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.

2016-03-31 Thread KatolaZ
On Thu, Mar 31, 2016 at 08:38:26AM -0300, Emiliano Marini wrote:
> +1
> 
> Besides, * and [] are interchangeable. You can define a string as an array
> and use it later as a pointer:
> 
> char s[] = "hola";
> char x = s[1]; // Here x = 'o'
> char y = *(s+2);   // Here y = 'l'
> 
> And vice versa:
> 
> char *s = "hola";
> char x = s[0]; // Here x = 'h'
> char y = *(s+3);   // Here y = 'a'
> 

Just to be pedantic here, "[]" is just syntactic sugar around the
dereference operator "*". And in fact "[]" did not even exist in the
first versions of proto-C. Obviously, "[]" is syntactic sugar around
unary "*" for *any* kind of pointer, not just for strings. 

Also, initialisation of char* and char[] by means of 

  char s[] = "hello";

is syntactic sugar around the generic initialiser:

  type p = {...};

which allows to initialise arrays and compound variables (structs and
unions) as well. But be careful with statically initialised strings,
since they are effectively constant char pointers (they are stored in
the current stack frame, not in the heap, and the address stored in
such variables cannot be modified, AFAIR).

My2Cents

KatolaZ

-- 
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-31 Thread Emiliano Marini
+1

Besides, * and [] are interchangeable. You can define a string as an array
and use it later as a pointer:

char s[] = "hola";
char x = s[1]; // Here x = 'o'
char y = *(s+2);   // Here y = 'l'

And vice versa:

char *s = "hola";
char x = s[0]; // Here x = 'h'
char y = *(s+3);   // Here y = 'a'



On Wed, Mar 30, 2016 at 6:04 PM, Rainer Weikusat <
rainerweiku...@virginmedia.com> wrote:

> Edward Bartolo  writes:
>
> > Hi, thanks for your help.
> >
> > So: [ I am recalling this from memory to test where I am ]
> > a)  type* pp; // declare a pointer pp
> > b) *pp = RHS; // assign RHS to the data pointed to by pp
> > c) type **ss; // declare a pointer to pointer. System only allocates
> > space for one address
>
> (1) Background
> --
>
> The C type system is built around the idea that certain kind of types can
> be
> derived from already existing types. These are pointers, arrays (and
> functions, but I'm going to omit them for simplicity). Eg, assuming type
> identifies and existing type,
>
> type *pt
>
> declares a pointer to objects of type type and
>
> type at[3];
>
> declares an array of objects of type type. When an object is defined,
> the system allocates storage for it in some suitable location, eg, on
> the stack or by reserving a register.
>
> (2)Typedef names
> 
>
> It's possible to create a new name for an existing type with the help of
> typedef, eg, after
>
> typedef int *pint;
>
> pint can be used as type name to mean 'pointer to int'. Eg,
>
> pint pi;
>
> would define an object of type 'pointer to int' (the compiler will
> allocate storage for).
>
> Pulling this together
> -
>
> Assuming pint is declared as above. As per (1), new types can now
> derived from it, eg,
>
> pint *ppi; /* "Dear customer ..." */
>
> This defines a "pointer to pint", hence, the system allocates storage
> for one. But that's really the same as
>
> int **ppi;
>
> which is handled in exactly the same way: An object with a pointer type
> derived from some existing type is defined. Hence, storage for a pointer
> is reserved. That the existing type is itself a pointer type doesn't
> matter, for the given purpose, it's just 'some type'.
>
>
> > f) strings are character arrays, so they obey the rules governing arrays
>
> They're really pointers to character arrays. Because an array is
> converted to a pointer to its first element most of the time, a
> character array, say
>
> char chars[] = "12345";
>
> can be used as if it had been declared as a pointer. There's one
> important difference:
>
> char chars[] = "12345";
>
> cause the compiler to reserve six bytes (five chars + terminating 0) in
> some location the program can write to. Afterwards,
>
> *chars = R;
>
> could be used to change the string to R2345. In contrast to this.
>
> char *chars = "12345";
>
> causes the compiler to allocate storage for a writable char * and
> initialize that with the address of a string literal which is not
> required to be (and usually won't be) writeable.
> ___
> 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.

2016-03-31 Thread Emiliano Marini
Exactly, any local variable comes off the stack, but I was talking about
pointers :)

On Wed, Mar 30, 2016 at 3:37 PM, Steve Litt 
wrote:

> On Wed, 30 Mar 2016 08:23:16 -0300
> Emiliano Marini  wrote:
>
> > Edward, the only time the compiler allocates memory for data
> > automatically is when using strings literals (as stated by Rainer
> > previously)
> >
> > char *p = "Hola mundo."
>
> Also when you have a struct as a local variable:
>
> struct my_cool_struct mystruct;
>
> Like the char pointer, it comes off the stack, not the heap it would
> come off if you used malloc().
>
> Actually, any local variable allocates memory off the stack. Consider:
>
> int number_of_people;
>
> The preceding allocates sizeof(int) bytes, for number_of_people, off
> the stack.
>
> 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.

2016-03-30 Thread Ulf-Rainer Tietz

On 2016-03-28 06:50:38 +, Edward Bartolo said:


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


Hi,
If you read the Usenet time Comp Lang C FAQ by Steve Summit you will 
find many answers and learn a lot about the C language. This helped me 
plenty coming from many asm languages.

https://www.eskimo.com/~scs/___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-30 Thread Rainer Weikusat
Edward Bartolo  writes:

> Hi, thanks for your help.
>
> So: [ I am recalling this from memory to test where I am ]
> a)  type* pp; // declare a pointer pp
> b) *pp = RHS; // assign RHS to the data pointed to by pp
> c) type **ss; // declare a pointer to pointer. System only allocates
> space for one address

(1) Background
--

The C type system is built around the idea that certain kind of types can be
derived from already existing types. These are pointers, arrays (and
functions, but I'm going to omit them for simplicity). Eg, assuming type
identifies and existing type,

type *pt

declares a pointer to objects of type type and

type at[3];

declares an array of objects of type type. When an object is defined,
the system allocates storage for it in some suitable location, eg, on
the stack or by reserving a register.

(2)Typedef names


It's possible to create a new name for an existing type with the help of
typedef, eg, after

typedef int *pint;

pint can be used as type name to mean 'pointer to int'. Eg,

pint pi;

would define an object of type 'pointer to int' (the compiler will
allocate storage for).

Pulling this together
-

Assuming pint is declared as above. As per (1), new types can now
derived from it, eg,

pint *ppi; /* "Dear customer ..." */

This defines a "pointer to pint", hence, the system allocates storage
for one. But that's really the same as

int **ppi;

which is handled in exactly the same way: An object with a pointer type
derived from some existing type is defined. Hence, storage for a pointer
is reserved. That the existing type is itself a pointer type doesn't
matter, for the given purpose, it's just 'some type'.


> f) strings are character arrays, so they obey the rules governing arrays

They're really pointers to character arrays. Because an array is
converted to a pointer to its first element most of the time, a
character array, say

char chars[] = "12345";

can be used as if it had been declared as a pointer. There's one
important difference:

char chars[] = "12345";

cause the compiler to reserve six bytes (five chars + terminating 0) in
some location the program can write to. Afterwards,

*chars = R;

could be used to change the string to R2345. In contrast to this.

char *chars = "12345";

causes the compiler to allocate storage for a writable char * and
initialize that with the address of a string literal which is not
required to be (and usually won't be) writeable.
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-30 Thread Edward Bartolo
Hi, thanks for your help.

So: [ I am recalling this from memory to test where I am ]
a)  type* pp; // declare a pointer pp
b) *pp = RHS; // assign RHS to the data pointed to by pp
c) type **ss; // declare a pointer to pointer. System only allocates
space for one address
d) *ss = RHS; // assign RHS to the pointer pointed to by ss.
e) const char* and char* are not the same ie treated differently by the compiler
f) strings are character arrays, so they obey the rules governing arrays
g) strings are terminated by a null character which is a byte with eight zeros
h) extra care must be taken when copying strings not to write beyond
the end of allocated memory. This can result in buffer overflows that
may cause execution of arbitrary code
i) some built in string function provided by C, especially vintage
string functions, suffer from the buffer overrun bug. Guard against
that by making sure there is enough memory allocated.
j) When calling backend CLI programs make sure, the input to the
calling function cannot be maliciously modified to allow execution of
arbitrary commands. Functions like execl can be abused so extra care
to block abuse must be taken.

Edward

On 30/03/2016, Steve Litt  wrote:
> On Wed, 30 Mar 2016 08:23:16 -0300
> Emiliano Marini  wrote:
>
>> Edward, the only time the compiler allocates memory for data
>> automatically is when using strings literals (as stated by Rainer
>> previously)
>>
>> char *p = "Hola mundo."
>
> Also when you have a struct as a local variable:
>
> struct my_cool_struct mystruct;
>
> Like the char pointer, it comes off the stack, not the heap it would
> come off if you used malloc().
>
> Actually, any local variable allocates memory off the stack. Consider:
>
> int number_of_people;
>
> The preceding allocates sizeof(int) bytes, for number_of_people, off
> the stack.
>
> 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.

2016-03-30 Thread Steve Litt
On Wed, 30 Mar 2016 08:23:16 -0300
Emiliano Marini  wrote:

> Edward, the only time the compiler allocates memory for data
> automatically is when using strings literals (as stated by Rainer
> previously)
> 
> char *p = "Hola mundo."

Also when you have a struct as a local variable:

struct my_cool_struct mystruct;

Like the char pointer, it comes off the stack, not the heap it would
come off if you used malloc().

Actually, any local variable allocates memory off the stack. Consider:

int number_of_people;

The preceding allocates sizeof(int) bytes, for number_of_people, off
the stack.

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.

2016-03-30 Thread Hendrik Boom
On Wed, Mar 30, 2016 at 09:16:22AM +0200, Edward Bartolo wrote:
> Hi and many thanks for the replies,
> 
> I can understand that a pointer being an address depends heavily on
> machine architecture which means, on 32 bit machines it is 4 bytes
> long and on 64 bit machines it is 8 bytes long. I also understand that
> a pointer variable is essentially made of two parts as illustrated
> below:
> 
> address [always allocated] --> data [not allocated
> automatically]
> 
> The address does depend on architecture but the data? And what else
> can enter into a pointer's definition other than what I illustrated?

Some machines (I'm thinking of, say, the PDP-10, which had a 36-bit 
wors soze, and, if I remember correctly, eighteen-bit addresses) found 
that it was good to stuff many characters into a single addressible 
machine word.  I think the PDP-10  stuffed five seven-bit characters 
into a word, leaving the sign bit unmolested.  But sometime it was 
necessary to address intividual characters within a word.  To this 
eend, they made special character pointers, which were a few bits 
longer than a regular address.  So character pointers were not the same 
size as regular pointers.

There are have also been systems where a function pointer has two 
compononts -- the address of the code to be executed and the address of 
the environment the function is to operate in.  There are historical 
reasos for that (mostly having to do with programming language that are 
not C), but on machines designed for that, function pointers will be 
bigger than  data pointers.

But C is part of the legacy of 8-bit bytes and byte-addressable 
machines.

-- hendrik
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-30 Thread Emiliano Marini
Edward, the only time the compiler allocates memory for data automatically
is when using strings literals (as stated by Rainer previously)

char *p = "Hola mundo."

This is because strings are a special case.

https://www.cs.uic.edu/~jbell/CourseNotes/C_Programming/CharacterStrings.html


On Wed, Mar 30, 2016 at 4:16 AM, Edward Bartolo  wrote:

> Hi and many thanks for the replies,
>
> I can understand that a pointer being an address depends heavily on
> machine architecture which means, on 32 bit machines it is 4 bytes
> long and on 64 bit machines it is 8 bytes long. I also understand that
> a pointer variable is essentially made of two parts as illustrated
> below:
>
> address [always allocated] --> data [not allocated
> automatically]
>
> The address does depend on architecture but the data? And what else
> can enter into a pointer's definition other than what I illustrated?
>
> Compound/complex pointer definitions like data_type** U, work as
> follows as far as my intellect can reason and deduce from what I
> studied and from my now long experience coding.
>
> address1[allocated] -> address2[NOT allocated] ->
> data_type[not allocated]
>
> My mistake was to assume in the case of data_type** U the compiler
> would allocate the two addresses and link them, that is, store the
> address of address2 in address1. The latter is not the case and a
> coder is required to first allocate space for the 2nd address. In
> fact, allocating space for void** ptr, in a sample program worked
> without issues. I am attaching this sample program.
>
> Edward
>
> On 29/03/2016, Rainer Weikusat  wrote:
> > Hendrik Boom  writes:
> >> On Tue, Mar 29, 2016 at 02:46:50PM +0100, Rainer Weikusat wrote:
> >>> This is a wrong assumption and it relies on behaviour the C standard
> >>> doesn't guarantee. Any pointer may be converted (it's even converted
> >>> automatically as required) to a void * and back and
> >>>
> >>> "the result shall compare equal to the original pointer"
> >>>
> >>> But a pointer to a void * is an entirely different animal and no such
> >>> guarantees are made for that. This will work in practice if there's
> only
> >>> one 'machine pointer type' anyway, though. But using it is not
> necessary
> >>> as void * is sufficient.
> >>
> >> Last time I looked at the C standard (which was a while ago, things may
> >> have changed) function pointers were not guaranteed to be
> >> interconvertable with data pointers.
> >
> > Indeed. I didn't remember this while writing the text.
> > ___
> > 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 mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-30 Thread Emiliano Marini
+1

On Wed, Mar 30, 2016 at 5:04 AM, KatolaZ  wrote:

> On Wed, Mar 30, 2016 at 09:16:22AM +0200, Edward Bartolo wrote:
> > Hi and many thanks for the replies,
> >
> > I can understand that a pointer being an address depends heavily on
> > machine architecture which means, on 32 bit machines it is 4 bytes
> > long and on 64 bit machines it is 8 bytes long. I also understand that
> > a pointer variable is essentially made of two parts as illustrated
> > below:
> >
> > address [always allocated] --> data [not allocated
> > automatically]
> >
> > The address does depend on architecture but the data? And what else
> > can enter into a pointer's definition other than what I illustrated?
> >
>
> Hi Edward,
>
> sorry but your description is incorrect. A pointer in C is just a
> variable large enough to contain a memory address. Period. There is no
> explicit or implicit linking between a pointer (which is a variable
> large enough to contain a memory address) and the area of memory it
> points to. You may have several pointers pointing to the same memory
> area. You can have the same pointer (i.e., the same named variable
> able to contain a memory address) pointing to different memory areas
> at different times. You can use a pointer to wander around an
> allocated memory area at your will, changing its value by using the
> powerful pointer arithmetic provided by C. You can also have some
> allocated memory area for which you don't have any pointer at all (and
> this is what is called a "memory leak", and you should avoid it).
>
> Also, memory areas are not "typed" in C, meaning that you can in
> principle access a correctly allocated memory area with pointers of
> any type, the only problem being the semantics of pointer arithmetics,
> which is entirely left to the programmer.
>
> But please forget any implicit linkage between a pointer (the
> variable) and the memory area it points to (i.e., the address
> contained in that variable), as you don't assume any intrinsic link
> between an integer variable and the possible values that the variable
> can contain. If you don't break this spell, you will never get around
> with C pointers.
>
> Pointers are just variables which are able to contain memory
> addresses. What you put in those variables does not bother them in any
> discernible way. And shouldn't bother you either, as long as you be
> careful in using them to refer to correctly allocated memory. SIGSEGV
> is the alternative.
>
> My2Cents
>
> KatolaZ
>
> --
> [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
> [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
> [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
> [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
> ___
> 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.

2016-03-30 Thread KatolaZ
On Wed, Mar 30, 2016 at 09:26:32AM +0200, Edward Bartolo wrote:
> Hi,
> 
> I can also understand that typecasting, that is, bypassing strict type
> checking, a void pointer without checking for architecture is like a
> time bomb. Addresses on different architectures can be different sizes
> and a typecast of void from an integer requires some conditions that
> must be true. Both void* and integer must have the same size on the
> target machine or code is written in a way to make sure a difference
> in architecture does not result in code being broken.
> 

void* and int happen to have the same size in i386 architectures, but
this is not always true. There is no implied correspondence between
void* and int that I am aware of. In my amd64 machine, all pointers
are 8 bytes, but an int is 4 bytes long.

Please do not make assumptions about the length of a pointer. The
typecasting referred before was *between pointers*, and not between
pointers and other types. This means that you can cast a void* to a
char* or to an int**, but not that you can cast a void* to a char.

Also, pointer arithmetic is defined (to the best of my knowledge) only
on typed pointers, so that something like:
 
  void *a;
  a = a +1;

is not meaningful (and I bet you should get a compile-time error),
while:

  void *a;
  a = (int*) a + 1;

is perfectly valid, and widely used.

My2Cents

KatolaZ

-- 
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-30 Thread Edward Bartolo
Hi,

I can also understand that typecasting, that is, bypassing strict type
checking, a void pointer without checking for architecture is like a
time bomb. Addresses on different architectures can be different sizes
and a typecast of void from an integer requires some conditions that
must be true. Both void* and integer must have the same size on the
target machine or code is written in a way to make sure a difference
in architecture does not result in code being broken.

Edward

On 30/03/2016, Edward Bartolo  wrote:
> Hi and many thanks for the replies,
>
> I can understand that a pointer being an address depends heavily on
> machine architecture which means, on 32 bit machines it is 4 bytes
> long and on 64 bit machines it is 8 bytes long. I also understand that
> a pointer variable is essentially made of two parts as illustrated
> below:
>
> address [always allocated] --> data [not allocated
> automatically]
>
> The address does depend on architecture but the data? And what else
> can enter into a pointer's definition other than what I illustrated?
>
> Compound/complex pointer definitions like data_type** U, work as
> follows as far as my intellect can reason and deduce from what I
> studied and from my now long experience coding.
>
> address1[allocated] -> address2[NOT allocated] ->
> data_type[not allocated]
>
> My mistake was to assume in the case of data_type** U the compiler
> would allocate the two addresses and link them, that is, store the
> address of address2 in address1. The latter is not the case and a
> coder is required to first allocate space for the 2nd address. In
> fact, allocating space for void** ptr, in a sample program worked
> without issues. I am attaching this sample program.
>
> Edward
>
> On 29/03/2016, Rainer Weikusat  wrote:
>> Hendrik Boom  writes:
>>> On Tue, Mar 29, 2016 at 02:46:50PM +0100, Rainer Weikusat wrote:
 This is a wrong assumption and it relies on behaviour the C standard
 doesn't guarantee. Any pointer may be converted (it's even converted
 automatically as required) to a void * and back and

 "the result shall compare equal to the original pointer"

 But a pointer to a void * is an entirely different animal and no such
 guarantees are made for that. This will work in practice if there's
 only
 one 'machine pointer type' anyway, though. But using it is not
 necessary
 as void * is sufficient.
>>>
>>> Last time I looked at the C standard (which was a while ago, things may
>>> have changed) function pointers were not guaranteed to be
>>> interconvertable with data pointers.
>>
>> Indeed. I didn't remember this while writing the text.
>> ___
>> 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.

2016-03-29 Thread Rainer Weikusat
Hendrik Boom  writes:
> On Tue, Mar 29, 2016 at 02:46:50PM +0100, Rainer Weikusat wrote:
>> This is a wrong assumption and it relies on behaviour the C standard
>> doesn't guarantee. Any pointer may be converted (it's even converted
>> automatically as required) to a void * and back and
>> 
>> "the result shall compare equal to the original pointer"
>> 
>> But a pointer to a void * is an entirely different animal and no such
>> guarantees are made for that. This will work in practice if there's only
>> one 'machine pointer type' anyway, though. But using it is not necessary
>> as void * is sufficient.
>
> Last time I looked at the C standard (which was a while ago, things may
> have changed) function pointers were not guaranteed to be 
> interconvertable with data pointers.

Indeed. I didn't remember this while writing the text.
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-29 Thread Hendrik Boom
On Tue, Mar 29, 2016 at 02:46:50PM +0100, Rainer Weikusat wrote:

> This is a wrong assumption and it relies on behaviour the C standard
> doesn't guarantee. Any pointer may be converted (it's even converted
> automatically as required) to a void * and back and
> 
> "the result shall compare equal to the original pointer"
> 
> But a pointer to a void * is an entirely different animal and no such
> guarantees are made for that. This will work in practice if there's only
> one 'machine pointer type' anyway, though. But using it is not necessary
> as void * is sufficient.

Last time I looked at the C standard (which was a while ago, things may
have changed) function pointers were not guaranteed to be 
interconvertable with data pointers.  You could cast them back and 
forth, but there was no guarantee they would survive the round trip.

-- hendrik
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-29 Thread Rainer Weikusat
Steve Litt  writes:
> 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.

That's not necessarily true. Eg, on a 64-bit Intel machine using gcc
4.7.2, this program


static long long *llp(void)
{
long long x;

x = -2;
return 
}

static void *ouch(void)
{
char *p;

*p = 3;
return 
}

int main(void)
{
llp();
ouch();

return 0;
}


will segfault because the pointer gets the value assigned to the long
long used earlier.


___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-29 Thread Rainer Weikusat
Edward Bartolo  writes:
> 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.

This is a wrong assumption and it relies on behaviour the C standard
doesn't guarantee. Any pointer may be converted (it's even converted
automatically as required) to a void * and back and

"the result shall compare equal to the original pointer"

But a pointer to a void * is an entirely different animal and no such
guarantees are made for that. This will work in practice if there's only
one 'machine pointer type' anyway, though. But using it is not necessary
as void * is sufficient.


#include 
#include 

enum {
CHAR =  1,
SHORT = sizeof(short),
INT =   sizeof(int),
LLONG = sizeof(long long)
};

static void alloc_int(void *p, int which)
{
void *area;

area = malloc(which);
switch (which) {
case CHAR:
*(char **)p = area;
break;

case SHORT:
*(short **)p = area;
break;

case INT:
*(int **)p = area;
break;

case LLONG:
*(long long **)p = area;
}
}

int main(void)
{
unsigned long long *pll;

alloc_int(, LLONG);
*pll = -1;
printf("%llx\n", *pll);

return 0;
}


NB: That's seriously bizarre code.

[...]

> 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;
> }

There's a return statement missing here or the declared return value is
wrong. It's a good idea to enable compiler warnings when compiling as
this means the compiler will - well - warn about such issues:

[rw@doppelsaurus]/tmp#gcc -W -Wall b.c
b.c: In function 'afunc':
b.c:6:1: warning: control reaches end of non-void function [-Wreturn-type]

Also, to state this again: C is not Pascal and doesn't distinguish
between 'subprograms which may return values and should/ must not have
side effects' (function) and 'subprograms which are executed for the
side effects but cannot return values except by using output
parameters'. When you're writing C, use the return value to return
values, eg

double afunc(double in)
{
return in * 2;
}

[...]

> The reason for this is the fact that a pointer is a number.

A machine address may be a number but a pointer isn't. That's something
abstract defined by C as having certain properties. Among these are that
pointers may be converted to integers and vice versa but the effect is
implementation dependent and the behaviour may be undefined. Again,
provided the integer has a sufficient size, this will usually
work. There are also optional types intptr_t and uintptr_t guaranteed to
be capable of storing the value of a void *.
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-29 Thread Emiliano Marini
This is correct:

int **L ===> Address1(preallocated) -> Address2(not allocated) ->
> int (not allocated)
>

When you declare a variable, the compiler will reserve memory space to
store it.

No matter how may asterisks a variable has, from the compiler's view it's
only a memory address. So it will reserve space to store an address:

int *x;

x will store a memory address, so the compiler has to reserve 8 bytes
(amd64) for it.

Conclusion: the size of a pointer will be always the same, no matter what
is pointing to (an integer, a char, an address...)


On Tue, Mar 29, 2016 at 9:00 AM, Edward Bartolo  wrote:

> Hi,
>
> As far as I know, the compiler automatically allocates memory for the
> address where a pointer is saved. The unallocated part is the data
> attached to a pointer. What happens with a pointer to a pointer like
> void**? Does the compiler allocate memory for two addresses with the
> first one in the chain pointing to the second one? Does it allocate
> memory only for the first address?
>
> What I can say about pointers:
>
> a) int * K ===>Address(preallocated) ---> integer
> [ not preallocated ]
>
> b) void** V ===> Address1 (preallocated) --> Address2(preallocated)
>
> OR:
>
> void** V ===> Address1 (preallocated) -> Address2(not preallocated)
>
> ?
>
> c) int **L ===> Address1 (preallocated) -> Address2(allocated)
> -> int (not allocated)
>
> OR
>
> int **L ===> Address1(preallocated) -> Address2(not allocated)
> -> int (not allocated)
>
> By 'preallocated' I mean the compiler will automatically generate code
> to allocate memory for the actual pointer not the data.
>
> d) Is this allowed: void***, int***, double***, etc?
> ___
> 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.

2016-03-29 Thread Edward Bartolo
Hi,

As far as I know, the compiler automatically allocates memory for the
address where a pointer is saved. The unallocated part is the data
attached to a pointer. What happens with a pointer to a pointer like
void**? Does the compiler allocate memory for two addresses with the
first one in the chain pointing to the second one? Does it allocate
memory only for the first address?

What I can say about pointers:

a) int * K ===>Address(preallocated) ---> integer
[ not preallocated ]

b) void** V ===> Address1 (preallocated) --> Address2(preallocated)

OR:

void** V ===> Address1 (preallocated) -> Address2(not preallocated)

?

c) int **L ===> Address1 (preallocated) -> Address2(allocated)
-> int (not allocated)

OR

int **L ===> Address1(preallocated) -> Address2(not allocated)
-> int (not allocated)

By 'preallocated' I mean the compiler will automatically generate code
to allocate memory for the actual pointer not the data.

d) Is this allowed: void***, int***, double***, etc?
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-29 Thread Edward Bartolo
Hi,

Sometimes, a generic pointer is very useful. For instance, the Windows
API documents functions that have untyped pointers. These allow great
flexibility and behave like the variant type in other languages but
with efficient memory consumption. Delphi Pascal has both the variant
and untyped pointer types. This clearly shows there are advantages to
having the possibility of using untyped pointers. The Windows API
CreateProcess function is such an example.

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.

2016-03-29 Thread KatolaZ
On Mon, Mar 28, 2016 at 09:55:08PM +0200, 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.
> 

Allocating memory for a generic variable into a function is seldom of
any use, since you need to specify how much memory (number of bytes)
your function should allocate anyway. Although it is still possible to
code such a function, I think it is in general a bad idea. Why don't
you use malloc directly for this purpose? 

Producing good-quality and maintanable software is also about
providing clean interfaces to the user, and by "interface" I mean
function signatures, which should be self-explanatory and clear. If I
can get almost anything as a result value of a function call, then
that function is likely to become a can of worms...

My2Cents

KatolaZ

-- 
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-28 Thread Emiliano Marini
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 =  // p has the address where i is located

  // Here *p is 0

  efgh(); // 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(); // [1]
  efgh();
  // 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


Re: [DNG] Making sense of C pointer syntax.

2016-03-28 Thread Edward Bartolo
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.

2016-03-28 Thread Rainer Weikusat
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.

2016-03-28 Thread Roger Leigh

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.

2016-03-28 Thread Rainer Weikusat
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 = ,
> -- 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.

2016-03-28 Thread Emiliano Marini
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.

2016-03-28 Thread Emiliano Marini
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.

2016-03-28 Thread Emiliano Marini
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()"), 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.

2016-03-28 Thread Rainer Weikusat
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.

2016-03-28 Thread Emiliano Marini
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.

2016-03-28 Thread karl
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 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.

2016-03-28 Thread aitor_czr

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.

2016-03-28 Thread Steve Litt
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 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.

2016-03-28 Thread Steve Litt
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.

2016-03-28 Thread Steve Litt
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.

2016-03-28 Thread karl
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.

2016-03-28 Thread karl
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.

2016-03-28 Thread karl
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 = ,
-- 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.

2016-03-28 Thread 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.
___
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng


Re: [DNG] Making sense of C pointer syntax.

2016-03-28 Thread karl
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();
printf("p = %d\n", p);

return 0;
}

The definition "void change_value(void* ptr);" doesn't preclude the
use
 double dd;
 change_value();

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**) );
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(); /* instead of change_value((void**) ); */

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.

2016-03-28 Thread 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. 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.

2016-03-28 Thread Rainer Weikusat
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();
  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.

2016-03-28 Thread karl
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.

2016-03-28 Thread Boruch Baum
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