470,811 Members | 1,144 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,811 developers. It's quick & easy.

C Pointer problem

Hi,

I can't understand why this code causes a "memory read exception" at
int x=**a;

void pass(int** a)
{
int x=**a;
}
void main()
{
int arr[2][2]={{1,2},{3,4}};
pass(arr);
}
The assignment of int int x=**a in the main function works.

Tanks for your help,
Markus

May 31 '06 #1
73 3457
Markus said:
Hi,

I can't understand why this code causes a "memory read exception" at
int x=**a;

void pass(int** a)
{
int x=**a;
}
void main()
main returns int.

If you can't even get the entry point right, what chance do you stand with
pointers?
{
int arr[2][2]={{1,2},{3,4}};
pass(arr);


pass() takes int **.

arr's value is taken as the address of its first element. Its first element
is an int[2] array, so the address of its first element has type int
(*)[2], which is not the same as int **.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 31 '06 #2
Markus wrote:
Hi,

I can't understand why this code causes a "memory read exception" at
int x=**a;

void pass(int** a)
{
int x=**a;
}
void main()
{
int arr[2][2]={{1,2},{3,4}};
pass(arr);
}
The assignment of int int x=**a in the main function works.


Did this really compile without any warnings or errors?

Brian
May 31 '06 #3
Default User said:
Markus wrote:
Hi,

I can't understand why this code causes a "memory read exception" at
int x=**a;

void pass(int** a)
{
int x=**a;
}
void main()
{
int arr[2][2]={{1,2},{3,4}};
pass(arr);
}
The assignment of int int x=**a in the main function works.


Did this really compile without any warnings or errors?


No.

foo.c:2: warning: no previous prototype for `pass'
foo.c: In function `pass':
foo.c:3: warning: unused variable `x'
foo.c: At top level:
foo.c:6: warning: function declaration isn't a prototype
foo.c:6: warning: return type of `main' is not `int'
foo.c: In function `main':
foo.c:8: warning: passing arg 1 of `pass' from incompatible pointer type

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 31 '06 #4
Richard Heathfield a écrit :
foo.c:2: warning: no previous prototype for `pass'
foo.c: In function `pass':
foo.c:3: warning: unused variable `x'
foo.c: At top level:
foo.c:6: warning: function declaration isn't a prototype
foo.c:6: warning: return type of `main' is not `int'
foo.c: In function `main':
foo.c:8: warning: passing arg 1 of `pass' from incompatible pointer type


lcc-win32 has:
D:\lcc\mc66\test>lcc -A tw2.c
Warning tw2.c: 3 x is assigned a value that is never used
Warning tw2.c: 6 old-style function definition for 'main'
Warning tw2.c: 6 missing prototype for 'main'
Warning tw2.c: 6 'void main()' is a non-ANSI definition
Warning tw2.c: 8 assignment of pointer to array 2 of int to pointer to
pointer to int
0 errors, 5 warnings

Basically all warnings are the same, with wording differences.
The first warning of gcc however, is not clear to me:

foo.c:2: warning: no previous prototype for `pass'

Why is that an eror?

The function definition is correct, and it wasn't
previously used. That looks correct to me.
May 31 '06 #5
Richard Heathfield wrote:
Default User said:
Markus wrote:
The assignment of int int x=**a in the main function works.


Did this really compile without any warnings or errors?


No.


Of course. It was a nudge to the OP to let him know that the compiler
doesn't issue diagnostics (just) because it doesn't like you.


Brian
May 31 '06 #6
2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:
Richard Heathfield a écrit :
foo.c:2: warning: no previous prototype for `pass'
foo.c: In function `pass':
foo.c:3: warning: unused variable `x'
foo.c: At top level:
foo.c:6: warning: function declaration isn't a prototype
foo.c:6: warning: return type of `main' is not `int'
foo.c: In function `main':
foo.c:8: warning: passing arg 1 of `pass' from incompatible pointer type

lcc-win32 has:
D:\lcc\mc66\test>lcc -A tw2.c
Warning tw2.c: 3 x is assigned a value that is never used
Warning tw2.c: 6 old-style function definition for 'main'


While void main() is a lot of things (none of them good), it is not an
old-style definition. Warning on empty brackets might make sense for
a declaration without a definition, it does NOT make sense for
a definition.
Warning tw2.c: 6 missing prototype for 'main'
Warning tw2.c: 6 'void main()' is a non-ANSI definition
Warning tw2.c: 8 assignment of pointer to array 2 of int to pointer to
pointer to int
0 errors, 5 warnings

Basically all warnings are the same, with wording differences.
The first warning of gcc however, is not clear to me:

foo.c:2: warning: no previous prototype for `pass'

Why is that an eror?

The function definition is correct, and it wasn't
previously used. That looks correct to me.

May 31 '06 #7
Jordan Abel wrote:
2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:

lcc-win32 has:
D:\lcc\mc66\test>lcc -A tw2.c
Warning tw2.c: 3 x is assigned a value that is never used
Warning tw2.c: 6 old-style function definition for 'main'
While void main() is a lot of things (none of them good), it is not an
old-style definition.


int main() is part of an an old style definition, or at least a
definition
that's been in style for a long time. ;)
Warning on empty brackets might make sense for
a declaration without a definition, it does NOT make sense for
a definition.


Compare...

int foo() { }

int main()
{
foo(42); /* no diagnostic required */
return 0;
}

With...

int foo(void) { }

int main()
{
foo(42); /* diagnostic required */
return 0;
}

--
Peter

May 31 '06 #8
On 31 May 2006 09:42:51 -0700, "Markus" <ma***@punjabi.net> wrote:
Hi,

I can't understand why this code causes a "memory read exception" at
int x=**a;
Because you lied to the compiler. Arrays are not pointers and
pointers are not arrays.

void pass(int** a)
{
int x=**a;
a is a pointer to pointer to int. To do determine the value of the
int itself, the following steps are required:

1 - Determine the value of a. It was passed "by value" to the
function using whatever calling convention is appropriate for your
system so this pretty straight forward.

2 - Use this value as the address of a pointer to int.

3 - Determine the value of this pointer.

4 - Use this value as the address of the int.

5 - Determine the value of the int.

6 - Store this value in x. (Not part of determining the value
but the concluding step in the initialization.)
}
void main()
int main(void) please.{
int arr[2][2]={{1,2},{3,4}};
pass(arr);
Since this statement has a syntax error and will not compile cleanly,
why did you bother to execute the code at all. If you did not see the
mandatory diagnostic, you need to up the warning level on your
compiler.

You pass a 2D array to the function. In this context, the array name
evaluates to the address of the first element with type pointer to
first element. In other words, this is identical to coding
pass(&arr[0]);

arr[0] is itself an array of 2 int. A pointer to arr[0] has type
pointer to array of 2 int, written as int (*)[2].

The syntax error is because an int(*)[2] is incompatible with an
int**. There is no implicit conversion between the two.

Apparently on your system the two pointer types have similar
representations (not uncommon). pass will take the value and treat it
as the address of a pointer to int (steps 1 and 2 above).

Undefined behavior #1. Since the address is actually the
address of arr[0] which is an array of 2 int, it is really the address
of arr[0][0], a normal int. You have no idea if the alignment of this
int is suitable for a pointer to int.

Undefined behavior #2. pass will attempt to use the value at
this location as the address of an int (steps 3 and 4 above). You
have no idea if the value of the int that is actually at that location
is a valid address. It could be an invalid address or even a trap
representation.

Undefined behavior #3. pass will attempt to extract the int
value at this "address" (step 5 above). Since the value at this new
address was an int and not an address to begin with, attempting to
dereference it should be an obvious no-no. This is probably where
your system decided enough was enough.
}
The assignment of int int x=**a in the main function works.
There is no a in main. Perhaps you meant
int x = **arr;

This would work because the compiler know arr is a 2D array. *arr is
identical to arr[0] which is a1D array. **arr is identical to *arr[0]
which is identical to arr[0][0] which is the first int in the 1D array
and a perfectly valid value to assign to the int x.

Tanks for your help,
Markus

Remove del for email
Jun 1 '06 #9
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>, Peter Nilsson wrote:
Jordan Abel wrote:
2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:
>
> lcc-win32 has:
> D:\lcc\mc66\test>lcc -A tw2.c
> Warning tw2.c: 3 x is assigned a value that is never used
> Warning tw2.c: 6 old-style function definition for 'main'


While void main() is a lot of things (none of them good), it is not an
old-style definition.


int main() is part of an an old style definition, or at least a
definition
that's been in style for a long time. ;)
Warning on empty brackets might make sense for
a declaration without a definition, it does NOT make sense for
a definition.


Compare...

int foo() { }

int main()
{
foo(42); /* no diagnostic required */


False. The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition, and empty brackets
that _are_ in part of a definition. And the latter is EXACTLY equivalent
to (void).
Jun 1 '06 #10
Jordan Abel a écrit :
2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:
Richard Heathfield a écrit :
foo.c:2: warning: no previous prototype for `pass'
foo.c: In function `pass':
foo.c:3: warning: unused variable `x'
foo.c: At top level:
foo.c:6: warning: function declaration isn't a prototype
foo.c:6: warning: return type of `main' is not `int'
foo.c: In function `main':
foo.c:8: warning: passing arg 1 of `pass' from incompatible pointer type

lcc-win32 has:
D:\lcc\mc66\test>lcc -A tw2.c
Warning tw2.c: 3 x is assigned a value that is never used
Warning tw2.c: 6 old-style function definition for 'main'

While void main() is a lot of things (none of them good), it is not an
old-style definition. Warning on empty brackets might make sense for
a declaration without a definition, it does NOT make sense for
a definition.

Interesting. Maybe you know where in the standard that is
stated?

Thanks
Warning tw2.c: 6 missing prototype for 'main'
Warning tw2.c: 6 'void main()' is a non-ANSI definition
Warning tw2.c: 8 assignment of pointer to array 2 of int to pointer to
pointer to int
0 errors, 5 warnings

Basically all warnings are the same, with wording differences.
The first warning of gcc however, is not clear to me:

foo.c:2: warning: no previous prototype for `pass'

Why is that an eror?

The function definition is correct, and it wasn't
previously used. That looks correct to me.

You did not answer my question.

jacob
Jun 1 '06 #11

Richard Heathfield wrote:
arr's value is taken as the address of its first element. Its first element
is an int[2] array, so the address of its first element has type int
(*)[2], which is not the same as int **.


But following the char **argv (right? or char *argv[]) can be regarded
as char argv[][]. No runtime errors occur upon it, just an early
compiling warning is issued.

#include <stdio.h>

int
/*main(int argc, char *argv[]) */ /* a */
/*main(int argc, char **argv) */ /* b */
main(int argc, char argv[][]) /* c */
{
char ch = **argv;
printf("ch: %c", ch);
}

/* a */
$ gcc -W -Wall -std=c99 -pedantic test.c
test.c: In function `main':
test.c:4: warning: unused parameter `argc'
$ ./a.out
ch: .$

/* b */
$ gcc -W -Wall -std=c99 -pedantic test.c
test.c: In function `main':
test.c:5: warning: unused parameter `argc'
$ ./a.out
ch: .$

/* c */
$ gcc -W -Wall -std=c99 -pedantic test.c
test.c:6: warning: array type has incomplete element type
test.c:7: warning: second argument of `main' should be `char **'
test.c: In function `main':
test.c:6: warning: unused parameter `argc'
$ ./a.out
ch: i$
$

Jun 1 '06 #12
Jordan Abel wrote:
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>, Peter Nilsson wrote:
Jordan Abel wrote:
2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:
>
> lcc-win32 has:
> D:\lcc\mc66\test>lcc -A tw2.c
> Warning tw2.c: 3 x is assigned a value that is never used
> Warning tw2.c: 6 old-style function definition for 'main'

While void main() is a lot of things (none of them good), it is not an
old-style definition.


int main() is part of an an old style definition, or at least a
definition
that's been in style for a long time. ;)
Warning on empty brackets might make sense for
a declaration without a definition, it does NOT make sense for
a definition.


Compare...

int foo() { }

int main()
{
foo(42); /* no diagnostic required */


False. The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition, and empty brackets
that _are_ in part of a definition. And the latter is EXACTLY equivalent
to (void).


This is not true. Please see
http://open-std.org/JTC1/SC22/WG14/www/docs/dr_317.htm
for an official answer stating so.

Jun 1 '06 #13
Harald van Dijk a écrit :
Jordan Abel wrote:
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>, Peter Nilsson wrote:
Jordan Abel wrote:

2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:

>lcc-win32 has:
>D:\lcc\mc66\test>lcc -A tw2.c
>Warning tw2.c: 3 x is assigned a value that is never used
>Warning tw2.c: 6 old-style function definition for 'main'

While void main() is a lot of things (none of them good), it is not an
old-style definition.

int main() is part of an an old style definition, or at least a
definition
that's been in style for a long time. ;)
Warning on empty brackets might make sense for
a declaration without a definition, it does NOT make sense for
a definition.

Compare...

int foo() { }

int main()
{
foo(42); /* no diagnostic required */


False. The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition, and empty brackets
that _are_ in part of a definition. And the latter is EXACTLY equivalent
to (void).

This is not true. Please see
http://open-std.org/JTC1/SC22/WG14/www/docs/dr_317.htm
for an official answer stating so.


Thanks for the reference. That makes things clear.
int fn() { }
provides NO prototype for "fn". Maybe the wording of gcc is better,
in this specific context.

"Old Style" could be reserved for

int fn(a,b)
int a;
double b;
{ // ...
}
Jun 1 '06 #14
jacob navia said:
Richard Heathfield a écrit :
foo.c:2: warning: no previous prototype for `pass'
foo.c: In function `pass':
foo.c:3: warning: unused variable `x'
foo.c: At top level:
foo.c:6: warning: function declaration isn't a prototype
foo.c:6: warning: return type of `main' is not `int'
foo.c: In function `main':
foo.c:8: warning: passing arg 1 of `pass' from incompatible pointer type

lcc-win32 has:

<snip>
Basically all warnings are the same, with wording differences.
Hardly surprising, for such a short program.

The first warning of gcc however, is not clear to me:

foo.c:2: warning: no previous prototype for `pass'

Why is that an eror?


Who said it was an error? It's a diagnostic message, that's all. Compilers
are free to provide any diagnostic messages they like, whenever they like,
so long as they provide at least one diagnostic message if the input source
contains any syntax errors or constraint violations.

In this case, the message appears because I asked for it, with the
-Wstrict-prototypes flag to gcc.

I really, really should not be having to explain this Janet and John stuff
to a C compiler writer.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 1 '06 #15
Richard Heathfield a écrit :
jacob navia said:

The first warning of gcc however, is not clear to me:

foo.c:2: warning: no previous prototype for `pass'

Why is that an eror?

Who said it was an error? It's a diagnostic message, that's all. Compilers
are free to provide any diagnostic messages they like, whenever they like,
so long as they provide at least one diagnostic message if the input source
contains any syntax errors or constraint violations.

In this case, the message appears because I asked for it, with the
-Wstrict-prototypes flag to gcc.


You did NOT nclude the flags you passed to the compiler in that message,
so I could not know them.

Now it is clear.

Jun 1 '06 #16
lovecreatesbeauty said:

Richard Heathfield wrote:
arr's value is taken as the address of its first element. Its first
element is an int[2] array, so the address of its first element has type
int (*)[2], which is not the same as int **.
But following the char **argv (right? or char *argv[]) can be regarded
as char argv[][].


No, there is no such type as char argv[][].
No runtime errors occur upon it, just an early
compiling warning is issued.


"just"? What planet are you on? Your compiler is saying:

* * * *
* * * *
* * * * * * * * * * * * * * * * * * * *
* * * * * * * *
* * * * * * * *

LLL OOOOO OOOOO KKK KKK !!!
LLL OOO OOO OOO OOO KKK KKK !!!
LLL OOO OOO OOO OOO KKK KKK !!!
LLL OOO OOO OOO OOO KKKKKK !!!
LLL OOO OOO OOO OOO KKK KKK
LLLLLL OOO OOO OOO OOO KKK KKK !!!
LLLLLL OOOOO OOOOO KKK KKK !!!

* * * *
* * * *
* * * * * * * * * * * * * * * * * * * *
* * * * * * * *
* * * * * * * *
and you're saying it's "just" a warning?

If you want to learn to be a real C programmer, one vital step on that road
is to crank up your warning level to the max. Once you've done that, learn
to *understand* the diagnostic messages your compiler produces.

In this case, the compiler is saying "WTH is char [][]?" and it is quite
right, for there is no such type. And if there is no such type, your code
should not refer to such a type, should it?

SO FIX YOUR CODE!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 1 '06 #17
jacob navia said:
Richard Heathfield a écrit :
jacob navia said:

The first warning of gcc however, is not clear to me:

foo.c:2: warning: no previous prototype for `pass'

Why is that an eror?

Who said it was an error? It's a diagnostic message, that's all.
Compilers are free to provide any diagnostic messages they like, whenever
they like, so long as they provide at least one diagnostic message if the
input source contains any syntax errors or constraint violations.

In this case, the message appears because I asked for it, with the
-Wstrict-prototypes flag to gcc.


You did NOT nclude the flags you passed to the compiler in that message,
so I could not know them.


So what? You should still know about the circumstances in which messages can
be produced, and you should still know that "diagnostic message" is not the
same as "error". That was all the information you needed to have at your
disposal to avoid asking the question "Why is that an eror?"

Let me get this straight - you didn't actually /write/ the core code for
lcc-win32, did you? Because if you did, I think it's time for me to start
warning people not to use it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 1 '06 #18
lovecreatesbeauty wrote:
Richard Heathfield wrote:
arr's value is taken as the address of its first element. Its first element
is an int[2] array, so the address of its first element has type int
(*)[2], which is not the same as int **.
But following the char **argv (right? or char *argv[]) can be regarded
as char argv[][].


No. At least, no more than you can regard a hungry alligator as a fluffy
toy. You might stoke it, it might not do anything, but it might take a
very large bite out of you.
No runtime errors occur upon it, just an early
compiling warning is issued.

#include <stdio.h>

int
/*main(int argc, char *argv[]) */ /* a */
/*main(int argc, char **argv) */ /* b */
main(int argc, char argv[][]) /* c */
{
char ch = **argv;
printf("ch: %c", ch);
}

/* a */
$ gcc -W -Wall -std=c99 -pedantic test.c
test.c: In function `main':
test.c:4: warning: unused parameter `argc'
$ ./a.out
ch: .$
<snip>
/* c */
$ gcc -W -Wall -std=c99 -pedantic test.c
test.c:6: warning: array type has incomplete element type
The above compiler warning says your program is not valid C. The
compiler could (and IMHO should) have aborted compilation at that point.
However, the standard only requires a diagnostic and then allows the
compiler to do anything it wants.
test.c:7: warning: second argument of `main' should be `char **'
Again, the compiler is telling you that you have got it wrong. How many
times do you have to be told something is wrong before you believe it?
test.c: In function `main':
test.c:6: warning: unused parameter `argc'
$ ./a.out
ch: i$
$


Here, if you actually look, you will see the program output is *not*
what you get from the correct program. So obviously with you three times
is not the charm.

Arrays are not pointers and pointers are not arrays. In particular, as
Richard clearly explained, a char ** parameter and a 2D array are
completely different beasts.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jun 1 '06 #19
On Wed, 31 May 2006 23:52:25 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:
Richard Heathfield a écrit :
foo.c:2: warning: no previous prototype for `pass'
foo.c: In function `pass':
foo.c:3: warning: unused variable `x'
foo.c: At top level:
foo.c:6: warning: function declaration isn't a prototype
foo.c:6: warning: return type of `main' is not `int'
foo.c: In function `main':
foo.c:8: warning: passing arg 1 of `pass' from incompatible pointer type


lcc-win32 has:
D:\lcc\mc66\test>lcc -A tw2.c
Warning tw2.c: 3 x is assigned a value that is never used
Warning tw2.c: 6 old-style function definition for 'main'
Warning tw2.c: 6 missing prototype for 'main'
Warning tw2.c: 6 'void main()' is a non-ANSI definition
Warning tw2.c: 8 assignment of pointer to array 2 of int to pointer to
pointer to int
0 errors, 5 warnings


And even the Microsoft VC++ compiler, cranked up all the way to
warning level 4, complains:

stdc.c(8) : warning C4047: 'function' : 'int ** ' differs in levels of
indirection from 'int [2][2]'
stdc.c(8) : warning C4024: 'pass' : different types for formal and
actual parameter 1

Conspicuously missing is the warning about "void main()". Microsoft
likes to accommodate those who would tempt to risk the wretched wrath
of undefined behavior. Keep in mind that the VC++ compiler only runs
on Windows, though.

--
jaysome
Jun 1 '06 #20
Richard Heathfield wrote:
Let me get this straight - you didn't actually /write/ the core code for
lcc-win32, did you? Because if you did, I think it's time for me to start
warning people not to use it.


Well, of course, the original LCC compiler was not written by Jacob. It
was written by Chris Fraser and David Hanson. LCC was written in a very
simple and well-documented way, and they published a book describing it
in detail.

Jacob has been hacking on Lcc-Win32 for a long time now - since 1995.
I'm sure he has a very good understanding of the compiler by now.

Simon.
Jun 1 '06 #21
2006-06-01 <11**********************@j55g2000cwa.googlegroups .com>, Harald van D?k wrote:
Jordan Abel wrote:
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>, Peter Nilsson wrote:
> Jordan Abel wrote:
>> 2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:
>> >
>> > lcc-win32 has:
>> > D:\lcc\mc66\test>lcc -A tw2.c
>> > Warning tw2.c: 3 x is assigned a value that is never used
>> > Warning tw2.c: 6 old-style function definition for 'main'
>>
>> While void main() is a lot of things (none of them good), it is not an
>> old-style definition.
>
> int main() is part of an an old style definition, or at least a
> definition
> that's been in style for a long time. ;)
>
>> Warning on empty brackets might make sense for
>> a declaration without a definition, it does NOT make sense for
>> a definition.
>
> Compare...
>
> int foo() { }
>
> int main()
> {
> foo(42); /* no diagnostic required */


False. The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition, and empty brackets
that _are_ in part of a definition. And the latter is EXACTLY equivalent
to (void).


This is not true. Please see
http://open-std.org/JTC1/SC22/WG14/www/docs/dr_317.htm
for an official answer stating so.


That interpretation does not follow from that wording. If that was
_really_ what they meant, they should have worded it differently. It
says "no parameters". The fact that there is any distinction at all
between "An empty list in a function declarator that is part of
a function definition" and one in one that is not, proves my point.

The standard is clear. If "the committee" is free to change the meaning
of the standard even when no ambiguity existed in the first place, then
the standard has no meaning at all.
Jun 1 '06 #22
2006-06-01 <44***********************@news.orange.fr>, jacob navia wrote:
Jordan Abel a écrit :
2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:
Richard Heathfield a écrit :

foo.c:2: warning: no previous prototype for `pass'
foo.c: In function `pass':
foo.c:3: warning: unused variable `x'
foo.c: At top level:
foo.c:6: warning: function declaration isn't a prototype
foo.c:6: warning: return type of `main' is not `int'
foo.c: In function `main':
foo.c:8: warning: passing arg 1 of `pass' from incompatible pointer type
lcc-win32 has:
D:\lcc\mc66\test>lcc -A tw2.c
Warning tw2.c: 3 x is assigned a value that is never used
Warning tw2.c: 6 old-style function definition for 'main'

While void main() is a lot of things (none of them good), it is not an
old-style definition. Warning on empty brackets might make sense for
a declaration without a definition, it does NOT make sense for
a definition.

Interesting. Maybe you know where in the standard that is
stated?


The sentence that the committee repudiates in the DR that someone
elsewhere in this thread linked.
Jun 1 '06 #23
Jordan Abel wrote:
2006-06-01 <11**********************@j55g2000cwa.googlegroups .com>, Harald van D?k wrote:
Jordan Abel wrote:
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>, Peter Nilsson wrote:
> Jordan Abel wrote:
>> 2006-05-31 <44***********************@news.wanadoo.fr>, jacob navia wrote:
>> >
>> > lcc-win32 has:
>> > D:\lcc\mc66\test>lcc -A tw2.c
>> > Warning tw2.c: 3 x is assigned a value that is never used
>> > Warning tw2.c: 6 old-style function definition for 'main'
>>
>> While void main() is a lot of things (none of them good), it is not an
>> old-style definition.
>
> int main() is part of an an old style definition, or at least a
> definition
> that's been in style for a long time. ;)
>
>> Warning on empty brackets might make sense for
>> a declaration without a definition, it does NOT make sense for
>> a definition.
>
> Compare...
>
> int foo() { }
>
> int main()
> {
> foo(42); /* no diagnostic required */

False. The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition, and empty brackets
that _are_ in part of a definition. And the latter is EXACTLY equivalent
to (void).


This is not true. Please see
http://open-std.org/JTC1/SC22/WG14/www/docs/dr_317.htm
for an official answer stating so.


That interpretation does not follow from that wording. If that was
_really_ what they meant, they should have worded it differently. It
says "no parameters". The fact that there is any distinction at all
between "An empty list in a function declarator that is part of
a function definition" and one in one that is not, proves my point.


The behaviour is defined in some cases if a function declared as int
f() is called with arguments. The behaviour is never defined if a
function defined as int f() is called with parameters. There seems to
be a good reason for the distinction to me.

If you say a diagnostic is required for foo(42), could you please tell
me which constraint you believe is violated?

Jun 2 '06 #24
Richard Heathfield a écrit :

So what? You should still know about the circumstances in which messages can
be produced, and you should still know that "diagnostic message" is not the
same as "error". That was all the information you needed to have at your
disposal to avoid asking the question "Why is that an eror?"

I have to confess that I was unsure at that warning, not seeing the
specific options to gcc, so I commited the sin of asking a question
something that Mr Heathfield doesn't forgive me.

Let me get this straight - you didn't actually /write/ the core code for
lcc-win32, did you? Because if you did, I think it's time for me to start
warning people not to use it.


Well, maybe is time to re-read your gcc manual too.
The -W option that you used is deprecated. Use -Wextra instead.

Did you know that?

Apparently no.

Ahhh GOTCHA!!!!

Isn't that silly really? Asking you a question is a crime? :-)

Peace

jacob
Jun 2 '06 #25
jacob navia said:
Well, maybe is time to re-read your gcc manual too.
The -W option that you used is deprecated. Use -Wextra instead.
So what?

(a) I don't agree that everything gcc deprecates is necessarily worthy of
deprecation.
(b) My version of gcc doesn't support -Wextra.
(c) This is an implementation issue, not a language issue.
Did you know that?
If the question is "did I know that an implementation version that I don't
use introduced a new flag that I don't have", then the answer is simple:
questions about specific implementations should be asked in newsgroups
devoted to those implementations.

We've explained this to you before.
Ahhh GOTCHA!!!!


Oh, grow up.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 2 '06 #26
On 1 Jun 2006 01:26:09 GMT, Jordan Abel <ra****@random.yi.org> wrote:
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>, Peter Nilsson wrote:

Compare...

int foo() { }

int main()
{
foo(42); /* no diagnostic required */


False. The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition, and empty brackets
that _are_ in part of a definition. And the latter is EXACTLY equivalent
to (void).


Where?

6.7.5.3p14 says "An empty
list in a function declarator that is part of a definition of that
function specifies that the
function has no parameters."

It does NOT say that it is or functions as a prototype.

6.9.1p7 says "If the declarator includes a parameter type list,"
meaning new=prototype form it "also serves as a
function prototype for later calls to the same function in the same
translation unit." It then proceeds to the other case "If the
declarator includes an identifier list," meaning old form which
includes empty parentheses, where it says no such thing.

_C++_ effectively has only prototype form and actually says the
reverse: 8.3.5[dcl.fct]p2 "The parameter list (void) is equivalent
to the empty parameter list." (for both declarations and definitions).

This is one of the several reasons people here keep saying like a
mantra that C++ is NOT a superset of C.

It is fairly easy for a compiler to produce a diagnostic in this case,
as good QoI. But it is not required by the C standard.

- David.Thompson1 at worldnet.att.net
Jun 19 '06 #27
Dave Thompson wrote:

On 1 Jun 2006 01:26:09 GMT, Jordan Abel <ra****@random.yi.org> wrote:
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>,
Peter Nilsson wrote:
int foo() { }
The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition,
and empty brackets that _are_ in part of a definition.
Where?


What?

N869
Index

( ) (parentheses punctuator), 6.7.5.3, 6.8.4, 6.8.5
[ ] (brackets punctuator), 6.7.5.2, 6.7.8
{ } (braces punctuator), 6.7.2.2, 6.7.2.3, 6.7.8, 6.8.2

--
pete
Jun 19 '06 #28
On Mon, 19 Jun 2006 11:02:31 GMT, pete <pf*****@mindspring.com> wrote:
Dave Thompson wrote:

On 1 Jun 2006 01:26:09 GMT, Jordan Abel <ra****@random.yi.org> wrote:
2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>,
Peter Nilsson wrote: int foo() { } The standard makes a very clear distinction between empty
brackets in a declaration not part of a definition,
and empty brackets that _are_ in part of a definition.

Where?


What?

N869
Index

( ) (parentheses punctuator), 6.7.5.3, 6.8.4, 6.8.5
[ ] (brackets punctuator), 6.7.5.2, 6.7.8
{ } (braces punctuator), 6.7.2.2, 6.7.2.3, 6.7.8, 6.8.2


Are you being dense? He obviously meant brackets in the en_GB (or UK?)
meaning, what en_US (and the standard) calls parentheses.

- David.Thompson1 at worldnet.att.net
Jun 26 '06 #29
Dave Thompson wrote:

On Mon, 19 Jun 2006 11:02:31 GMT, pete <pf*****@mindspring.com> wrote:
Dave Thompson wrote:

On 1 Jun 2006 01:26:09 GMT,
Jordan Abel <ra****@random.yi.org> wrote:

> 2006-05-31
> <11*********************@c74g2000cwc.googlegroups. com>,
> Peter Nilsson wrote:
> > int foo() { }

> The standard makes a very clear distinction between empty
> brackets in a declaration not part of a definition,
> and empty brackets that _are_ in part of a definition.

Where?


What?

N869
Index

( ) (parentheses punctuator), 6.7.5.3, 6.8.4, 6.8.5
[ ] (brackets punctuator), 6.7.5.2, 6.7.8
{ } (braces punctuator), 6.7.2.2, 6.7.2.3, 6.7.8, 6.8.2


Are you being dense?


I am dense.
He obviously meant brackets in the en_GB (or UK?)
meaning, what en_US (and the standard) calls parentheses.


The example shown had empty parentheses and empty braces
and he was saying something that you suggest was false
about empty brackets.
So where's my clue as to what he's talking about?

--
pete
Jun 26 '06 #30
On 2006-06-26, Dave Thompson <da*************@worldnet.att.net> wrote:
On Mon, 19 Jun 2006 11:02:31 GMT, pete <pf*****@mindspring.com> wrote:
Dave Thompson wrote:
>
> On 1 Jun 2006 01:26:09 GMT, Jordan Abel <ra****@random.yi.org> wrote:
>
> > 2006-05-31 <11*********************@c74g2000cwc.googlegroups. com>,
> > Peter Nilsson wrote:

> > > int foo() { }

> > The standard makes a very clear distinction between empty
> > brackets in a declaration not part of a definition,
> > and empty brackets that _are_ in part of a definition.

> Where?


What?

N869
Index

( ) (parentheses punctuator), 6.7.5.3, 6.8.4, 6.8.5
[ ] (brackets punctuator), 6.7.5.2, 6.7.8
{ } (braces punctuator), 6.7.2.2, 6.7.2.3, 6.7.8, 6.8.2


Are you being dense? He obviously meant brackets in the en_GB (or UK?)
meaning, what en_US (and the standard) calls parentheses.


I know a lot of people who refer to []{}<>() as brackets (and some who
call quotes brackets), and it's much easier to just define everything
one way and act dense when others define them differently.

Sure, it was obvious that he didn't mean [] by "bracket". But what /did/
he mean? There was an empty () and an empty {} in the code.
Just my thoughts on why people don't like to talk to me. :-)

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.
Jun 26 '06 #31
pete wrote:

Dave Thompson wrote:

On Mon, 19 Jun 2006 11:02:31 GMT, pete <pf*****@mindspring.com> wrote:
Dave Thompson wrote:
>
> On 1 Jun 2006 01:26:09 GMT,
> Jordan Abel <ra****@random.yi.org> wrote:
>
> > 2006-05-31
> > <11*********************@c74g2000cwc.googlegroups. com>,
> > Peter Nilsson wrote:

> > > int foo() { }

> > The standard makes a very clear distinction between empty
> > brackets in a declaration not part of a definition,
> > and empty brackets that _are_ in part of a definition.

> Where?

What?

N869
Index

( ) (parentheses punctuator), 6.7.5.3, 6.8.4, 6.8.5
[ ] (brackets punctuator), 6.7.5.2, 6.7.8
{ } (braces punctuator), 6.7.2.2, 6.7.2.3, 6.7.8, 6.8.2


Are you being dense?


I am dense.


My point actually is that I always advocate using
C standard terminology when discussing the C standard
on this newsgroup.

--
pete
Jun 26 '06 #32
On Mon, 26 Jun 2006 02:30:03 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:

The example shown had empty parentheses and empty braces
and he was saying something that you suggest was false
about empty brackets.
It was, obviously, contained within the brackets. -)
So where's my clue as to what he's talking about?


Two nations divided by a common language indeed.

For the record, brackets come in three flavours, square, wiggly and
plain.

gd&r
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 26 '06 #33

Mark McIntyre wrote:

For the record, brackets come in three flavours, square, wiggly and
plain.


I've heard them called "curly, "squiggly", and "squirrely", but
I don't believe i've ever seen them called "wiggly" before. (I think I
usually call them "curly brackets" or sometimes "braces").

-Bill

Jun 27 '06 #34
Mark McIntyre wrote:
On Mon, 26 Jun 2006 02:30:03 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:

The example shown had empty parentheses and empty braces
and he was saying something that you suggest was false
about empty brackets.


It was, obviously, contained within the brackets. -)
So where's my clue as to what he's talking about?


Two nations divided by a common language indeed.

For the record, brackets come in three flavours, square, wiggly and
plain.


You forgot <pointy>.

--
Chris "ouch!" Dollin
"No-one here is exactly what he appears." G'kar, /Babylon 5/

Jun 27 '06 #35
Mark McIntyre wrote:
For the record, brackets come in three flavours, square, wiggly and
plain.


Four flavours:

(normal brackets)
[square brackets]
{curly brackets}
<angle brackets>

Even a simple C program uses all four flavours:

#include <stdio.h> // angle brackets
int main(int argc, char **argv) // normal brackets
{
printf("program name: %s\n",
argv[0] ? argv[0] // square brackets
: "none");
return 0;
} // curly brackets

Someone tell me, does one learn PODMAS instead of BODMAS in the USA?
(Brackets, Orders, Division/Multiplication, Addition/Subtraction)

--
Simon.
Jun 27 '06 #36
Simon Biber posted:

Someone tell me, does one learn PODMAS instead of BODMAS in the USA?

I actually learned BOMDAS at school, rather than "BODMAS".

Brackets
Off
Multiply
Divide
Add
Substract
Looks like we'd interpret the following differently:
5 * 4 / 2 * 5


If we multiply first, we get 2.
If we divide first, we get 50.
But of course C gives them equal precedence and works left to right, so
we'd get 50.

--

Frederick Gotham
Jun 27 '06 #37
Frederick Gotham wrote:
Simon Biber posted:

Someone tell me, does one learn PODMAS instead of BODMAS in the USA?

I actually learned BOMDAS at school, rather than "BODMAS".

Brackets
Off
Multiply
Divide
Add
Substract


It makes no difference. Either way you have to remember that Multiply
and Divide have equal precedence and are evaluated left to right.
Similarly, Add and Subtract have equal precedence and are evaluated left
to right.
Looks like we'd interpret the following differently:
5 * 4 / 2 * 5
If we multiply first, we get 2.
If we divide first, we get 50.


The correct answer is 50, however it's just by chance that this is also
achieved by dividing first.

In general you do not achieve the correct answer by multiplying first or
by dividing first, but rather by working left to right.

--
Simon.
Jun 27 '06 #38
Simon Biber posted:

In general you do not achieve the correct answer by multiplying first or
by dividing first, but rather by working left to right.

Yes I am well aware of how C operator precedence works -- I was referring
to the way human beings do math.

On the European side of the Atlantic, we learn BOMDAS rather than BODMAS,
and this would lead us to interpret the following line differently:

4 * 12 / 3 * 8
C compiler interpretation: 128

American interpretation: 128

European interpretation: 2

--

Frederick Gotham
Jun 27 '06 #39
On Tue, 27 Jun 2006 18:56:04 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.com> wrote:
On the European side of the Atlantic, we learn BOMDAS rather than BODMAS,
and this would lead us to interpret the following line differently:

4 * 12 / 3 * 8
C compiler interpretation: 128

American interpretation: 128

European interpretation: 2


Euh. only if you put in some brackets. I can't otherwise see how four
times twelve thirds times eight can equal two.

But then, everything *is* bigger in the States. :-)
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 27 '06 #40

Frederick Gotham wrote:
Simon Biber posted:

In general you do not achieve the correct answer by multiplying first or
by dividing first, but rather by working left to right.

Yes I am well aware of how C operator precedence works -- I was referring
to the way human beings do math.

On the European side of the Atlantic, we learn BOMDAS rather than BODMAS,
and this would lead us to interpret the following line differently:

4 * 12 / 3 * 8


That's the same as

4 * 12 * 1/3 * 8 == 128

Now had you wrote it as 4 * 12 / (3 * 8) then you'd have two.

That's like if you wrote

4 + 12 - 3 + 8

Does that mean

4 + 12 - (3 + 8) ?

No?

Then why does

4 * 12 / 3 * 8 mean 4*12/(3*8)?

.....

Tom

Jun 27 '06 #41
Mark McIntyre posted:
On Tue, 27 Jun 2006 18:56:04 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.com> wrote:
On the European side of the Atlantic, we learn BOMDAS rather than
BODMAS, and this would lead us to interpret the following line
differently:

4 * 12 / 3 * 8
C compiler interpretation: 128

American interpretation: 128

European interpretation: 2


Euh. only if you put in some brackets. I can't otherwise see how four
times twelve thirds times eight can equal two.

But then, everything *is* bigger in the States. :-)

Should I wait for you to re-post acknowledging your mistake, or should I
post the solution now?
If we multiply first, we get:

4*12 divided by 3*8

which becomes:

48 divided by 24

which becomes:

2
--

Frederick Gotham
Jun 27 '06 #42
Frederick Gotham wrote:
Should I wait for you to re-post acknowledging your mistake, or should I
post the solution now?
If we multiply first, we get:

4*12 divided by 3*8
But that isn't what you wrote. You wrote 4*12/3*8.
which becomes:

48 divided by 24


No that becomes 4*4*8.

Not only does logic dictate that but GNU BC, Perl and GCC all agree
that 4*12/3*8 is 128.

And the rule is BEDMAS not BODMAS which stands for Brackets, Exponents,
Division AND Multiplication, Addition AND Subtraction.

Note the use of AND.

By your logic 4+12-3+8 is 5.

Tom

Jun 27 '06 #43
In article <8b*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.com> wrote:
On the European side of the Atlantic, we learn BOMDAS rather than BODMAS,


Educational standards must have dropped since my day then.

There is no difference in precedence between multiplication and
division.

The same goes for addition and subtraction. Do you think that 3-2+1
is 0?

-- Richard
Jun 27 '06 #44
Frederick Gotham said:
Simon Biber posted:

In general you do not achieve the correct answer by multiplying first or
by dividing first, but rather by working left to right.

Yes I am well aware of how C operator precedence works -- I was referring
to the way human beings do math.

On the European side of the Atlantic, we learn BOMDAS rather than BODMAS,


Presumably that's on the European side of the English Channel, too. On the
/English/ side of the English Channel, I learned BODMAS at school, and my
children report that they, too, have learned BODMAS.
and this would lead us to interpret the following line differently:

4 * 12 / 3 * 8
C compiler interpretation: 128

American interpretation: 128

European interpretation: 2


English interpretation: Four lots of twelve and thruppence is two pounds
nine shillings; eight times that is nineteen pounds twelve, which is seven
quid for you and twelve guineas for me.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 27 '06 #45
Richard Heathfield schrieb:
Frederick Gotham said:
Simon Biber posted:
In general you do not achieve the correct answer by multiplying first or
by dividing first, but rather by working left to right.


Yes I am well aware of how C operator precedence works -- I was referring
to the way human beings do math.

On the European side of the Atlantic, we learn BOMDAS rather than BODMAS,


Presumably that's on the European side of the English Channel, too. On the
/English/ side of the English Channel, I learned BODMAS at school, and my
children report that they, too, have learned BODMAS.


I never learnt any BODMAS or BOMDAS -- I just learned the precedence
rules (as in "Punkt vor Strich" ;-)).
and this would lead us to interpret the following line differently:

4 * 12 / 3 * 8
C compiler interpretation: 128

American interpretation: 128

European interpretation: 2


English interpretation: Four lots of twelve and thruppence is two pounds
nine shillings; eight times that is nineteen pounds twelve, which is seven
quid for you and twelve guineas for me.


Write one hundred times
"Decimalisation and Metric System are good for us,
we are looking forward to adopt whatever else Brussels
throws at us".
*g,d&r*
SCNR
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Jun 27 '06 #46
In article <4g*************@individual.net>,
Michael Mair <Mi**********@invalid.invalid> wrote:
"Decimalisation and Metric System are good for us,
we are looking forward to adopt whatever else Brussels
throws at us".


Decimalisation was announced years before Britain negotiated entry to
the EEC. And metrication would have happened anyway.

Anyway, a rod-pole-or-perch can be approximated as 5m for most purposes.

-- Richard
Jun 28 '06 #47
Mark McIntyre <ma**********@spamcop.net> writes:
On Tue, 27 Jun 2006 18:56:04 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.com> wrote:
On the European side of the Atlantic, we learn BOMDAS rather than BODMAS,
and this would lead us to interpret the following line differently:

4 * 12 / 3 * 8

C compiler interpretation: 128

American interpretation: 128

European interpretation: 2


Euh. only if you put in some brackets. I can't otherwise see how four
times twelve thirds times eight can equal two.

But then, everything *is* bigger in the States. :-)


It seems obvious to me that *if* "*" binds more tightly than "/", then
the above expression

4 * 12 / 3 * 8

is equivalent to

(4 * 12) / (3 * 8)

which evaluates to 2.

There's nothing inherently inconsistent about a system in which "*"
binds more tightly than "/", but I've never heard of one. Certainly
we're all in agreement that they have the same precedence in C; I've
never encountered any other programming language in which they have
different precedence. In ordinary arithmetic as I learned it, they
have the same precedence, and the expression evaluates to 128. It's
not inconceivable that they have different precedence in some parts of
Europe, but if so this is the first I've heard of it.

I *probably* wouldn't write an expression like that that mixes "*" and
"/"; I'd likely add parentheses or even rearrange the expression, not
because it's ambiguous but because it's not immediately obvious.

In hand-written arithmetic, division is commonly represented as a
horizontal line rather than as an operator, so precedence is
determined by the placement of the parts of the expression:

4 * 12
------ * 8
3

or

12
4 * -- * 8
4

which avoids any ambiguity in the first place.

(BTW, I never learned "BOMDAS" or "BODMAS"; I just learned the rules.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 28 '06 #48
Richard Heathfield posted:

On the European side of the Atlantic, we learn BOMDAS rather than
BODMAS,


Presumably that's on the European side of the English Channel, too. On
the /English/ side of the English Channel, I learned BODMAS at school,
and my children report that they, too, have learned BODMAS.

I'm in Dublin in Ireland. I learned "BOMDAS" at school when I was either
ten or eleven, and that's only nine years ago -- but nevertheless, they may
have changed it in the meantime.
--

Frederick Gotham
Jun 28 '06 #49
Frederick Gotham said:
Richard Heathfield posted:

On the European side of the Atlantic, we learn BOMDAS rather than
BODMAS,


Presumably that's on the European side of the English Channel, too. On
the /English/ side of the English Channel, I learned BODMAS at school,
and my children report that they, too, have learned BODMAS.

I'm in Dublin in Ireland. I learned "BOMDAS" at school when I was either
ten or eleven, and that's only nine years ago -- but nevertheless, they
may have changed it in the meantime.


Ah, my apologies. You're on the European side of the /Irish/ Channel. :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 28 '06 #50

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Carsten Spieß | last post: by
5 posts views Thread by John N. | last post: by
7 posts views Thread by Mike D. | last post: by
10 posts views Thread by Kieran Simkin | last post: by
204 posts views Thread by Alexei A. Frounze | last post: by
7 posts views Thread by Marcelo | last post: by
51 posts views Thread by Joe Van Dyk | last post: by
2 posts views Thread by toton | last post: by
9 posts views Thread by junky_fellow | last post: by
6 posts views Thread by worlman385 | last post: by
reply views Thread by mihailmihai484 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.