Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #61077 > unrolled thread
| Started by | Bartc <bc@freeuk.com> |
|---|---|
| First post | 2015-04-25 13:19 +0100 |
| Last post | 2015-04-28 08:34 -0700 |
| Articles | 19 — 9 participants |
Back to article view | Back to comp.lang.c
Syntax error? Bartc <bc@freeuk.com> - 2015-04-25 13:19 +0100
Re: Syntax error? Richard Damon <Richard@Damon-Family.org> - 2015-04-25 11:07 -0400
Re: Syntax error? jacobnavia <jacob@jacob.remcomp.fr> - 2015-04-25 18:03 +0200
Re: Syntax error? Bartc <bc@freeuk.com> - 2015-04-25 17:26 +0100
Re: Syntax error? jacobnavia <jacob@jacob.remcomp.fr> - 2015-04-25 19:28 +0200
Re: Syntax error? Johannes Bauer <dfnsonfsduifb@gmx.de> - 2015-04-26 11:19 +0200
Re: Syntax error? Bartc <bc@freeuk.com> - 2015-04-26 11:17 +0100
Re: Syntax error? Bartc <bc@freeuk.com> - 2015-04-26 11:36 +0100
Re: Syntax error? Ben Bacarisse <ben.lists@bsb.me.uk> - 2015-04-26 13:40 +0100
Re: Syntax error? Bartc <bc@freeuk.com> - 2015-04-26 19:27 +0100
Re: Syntax error? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-04-26 12:38 -0700
Re: Syntax error? Bartc <bc@freeuk.com> - 2015-04-26 22:26 +0100
Re: Syntax error? Keith Thompson <kst-u@mib.org> - 2015-04-26 12:41 -0700
Re: Syntax error? Ben Bacarisse <ben.lists@bsb.me.uk> - 2015-04-27 01:53 +0100
Re: Syntax error? Bartc <bc@freeuk.com> - 2015-04-26 13:24 +0100
Re: Syntax error? Tim Rentsch <txr@alumni.caltech.edu> - 2015-04-26 07:01 -0700
Re: Syntax error? Bartc <bc@freeuk.com> - 2015-04-26 19:55 +0100
Re: Syntax error? Robert Wessel <robertwessel2@yahoo.com> - 2015-04-27 02:39 -0500
Re: Syntax error? Tim Rentsch <txr@alumni.caltech.edu> - 2015-04-28 08:34 -0700
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-25 13:19 +0100 |
| Subject | Syntax error? |
| Message-ID | <mhg0mq$f25$1@dont-email.me> |
How fast can you spot the problem in this code: *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); It was somewhat harder for me as the compiler says nothing about it until the next function dozens of lines later and then it picks on something totally unrelated. I think this is a design fault in the language syntax. (This is generated code and should ideally be: sptr->value = x->value/y->value; perhaps with a few extra parentheses, however the field selections have been earlier converted to byte offsets and it was awkward to recover the field names in certain consecutive sequences of field selections. But the above method should always work, at least when this problem is fixed.) -- Bartc
[toc] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2015-04-25 11:07 -0400 |
| Message-ID | <B4O_w.390543$2j2.147662@fx23.iad> |
| In reply to | #61077 |
On 4/25/15 8:19 AM, Bartc wrote: > How fast can you spot the problem in this code: > > *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); > > It was somewhat harder for me as the compiler says nothing about it > until the next function dozens of lines later and then it picks on > something totally unrelated. > > I think this is a design fault in the language syntax. > > (This is generated code and should ideally be: > > sptr->value = x->value/y->value; > > perhaps with a few extra parentheses, however the field selections have > been earlier converted to byte offsets and it was awkward to recover the > field names in certain consecutive sequences of field selections. But > the above method should always work, at least when this problem is fixed.) > Just shows how a bit of white space to make the code more readable can help.
[toc] | [prev] | [next] | [standalone]
| From | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| Date | 2015-04-25 18:03 +0200 |
| Message-ID | <mhgdrc$28e$1@dont-email.me> |
| In reply to | #61077 |
Le 25/04/2015 14:19, Bartc a écrit :
> *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8));
lcc-win has NO problems to compile that.
.file "d:\lcc\test\expr.c"
.text 64
; 1 void fn(char *sptr, char *x, char *y)
.type fn,function
.align 4
fn:
push %rbp
mov %rsp,%rbp
push %r15
subq $40,%rsp
movq %r8,32(%rbp)
movq %rdx,%r15
movq %rcx,16(%rbp)
; 2 {
; 3 *(int (*))((char*)sptr+8)=
; 4 (
; 5 *(int (*)) ((char*)x+8) / *(int (*)) ((char*)y+8)
; 6 );
; 7 }
movq %rcx,%r11
movslq 8(%r15),%rax
movq %r8,%r10
movslq 8(%r10),%rcx
cdq
idivl %ecx
movl %eax,8(%r11)
_$1:
addq $40,%rsp
pop %r15
leave
ret
_$2:
.size fn,_$2-fn
.globl fn
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-25 17:26 +0100 |
| Message-ID | <mhgf5i$7d6$1@dont-email.me> |
| In reply to | #61089 |
On 25/04/2015 17:03, jacobnavia wrote:
> Le 25/04/2015 14:19, Bartc a écrit :
>> *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int
>> (*))((char*)y+8));
>
> lcc-win has NO problems to compile that.
I should have added some definitions for sptr, x and y, but anything
will do for compiling it (but don't run the result):
int main (void) {
int sptr, x, y;
*(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8));
}
Maybe you missed what the problem was, and I didn't want to give it
away, but there's a "/*" sequence in the expression which inadvertently
starts off a comment. This is intended to be a divide symbol followed by
a dereference "*".
lcc-win says "EOF inside comment" compiling the above (in the real
version, it will just give unrelated errors later on). I noticed you
inserted a space between "/" and "*" before compiling it!
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| Date | 2015-04-25 19:28 +0200 |
| Message-ID | <mhgiqm$m7s$1@dont-email.me> |
| In reply to | #61090 |
Le 25/04/2015 18:26, Bartc a écrit : > lcc-win says "EOF inside comment" compiling the above (in the real > version, it will just give unrelated errors later on). I noticed you > inserted a space between "/" and "*" before compiling it! > Yeah, I tried to understand that stuff. OK, problem solved then.
[toc] | [prev] | [next] | [standalone]
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2015-04-26 11:19 +0200 |
| Message-ID | <mhiaif$7fj$1@news.albasani.net> |
| In reply to | #61077 |
On 25.04.2015 14:19, Bartc wrote: > How fast can you spot the problem in this code: > > *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); Since you already solved the mystery, I've got an unrelated question. Is there a reason why the code generate puts the "*" in braces for "int (*)"? I'm guessing there is, but I can't figure it out on the top of my head. Cheers, Johannes -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-26 11:17 +0100 |
| Message-ID | <mhidu2$igd$1@dont-email.me> |
| In reply to | #61120 |
On 26/04/2015 10:19, Johannes Bauer wrote: > On 25.04.2015 14:19, Bartc wrote: >> How fast can you spot the problem in this code: >> >> *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); > > Since you already solved the mystery, I've got an unrelated question. Is > there a reason why the code generate puts the "*" in braces for "int > (*)"? I'm guessing there is, but I can't figure it out on the top of my > head. You mean, in parentheses? This is just my algorithm for converting an internal representation of the type into C type-spec syntax. It was easier to put the parentheses in everywhere than to try and figure out where they can be omitted. But I suppose I can suppress them in the simplest of cases such as the above. (AFAIK this doesn't affect the resulting code in any way. But converting field selections to casts and offsets may be affecting code optimisation so I will try and tidy that up.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-26 11:36 +0100 |
| Message-ID | <mhif2c$mkd$1@dont-email.me> |
| In reply to | #61123 |
On 26/04/2015 11:17, Bartc wrote:
> On 26/04/2015 10:19, Johannes Bauer wrote:
>> On 25.04.2015 14:19, Bartc wrote:
>>> *(int (*))....
>> Is
>> there a reason why the code generate puts the "*" in braces for "int
>> (*)"?
> (AFAIK this doesn't affect the resulting code in any way.
Not completely true, as at least one compiler doesn't like this for example:
int (*fred(int a)) {
return 0;
}
But the same compiler is not going to like a lot of the C code I will
generate so I don't care!
Also, there is this example:
int *fred(int); // prototype for above
int *ptr; // pointer to int
If I add parentheses around the *name parts:
int (*fred)(int);
int (*ptr);
The int pointer is unaffected, but the first line now turns from a
function returning a pointer, to a pointer to a function! And therefore
the (int) following is an error. It is necessary to include the
parameter list within the parentheses.
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.lists@bsb.me.uk> |
|---|---|
| Date | 2015-04-26 13:40 +0100 |
| Message-ID | <87vbgj12rj.fsf@bsb.me.uk> |
| In reply to | #61124 |
Bartc <bc@freeuk.com> writes: <snip> > Also, there is this example: > > int *fred(int); // prototype for above > int *ptr; // pointer to int > > If I add parentheses around the *name parts: > > int (*fred)(int); > int (*ptr); > > The int pointer is unaffected, but the first line now turns from a > function returning a pointer, to a pointer to a function! Of course. Randomly adding parentheses into some syntax may alter the meaning. I really don't think that needs an exclamation mark. I get that you don't like the syntax, but this most recent objection to it -- that it is not immune to the insertion of key syntactic elements -- is just daft. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-26 19:27 +0100 |
| Message-ID | <mhjaka$3ja$1@dont-email.me> |
| In reply to | #61129 |
On 26/04/2015 13:40, Ben Bacarisse wrote: > Bartc <bc@freeuk.com> writes: > <snip> >> Also, there is this example: >> >> int *fred(int); // prototype for above >> int *ptr; // pointer to int >> >> If I add parentheses around the *name parts: >> >> int (*fred)(int); >> int (*ptr); >> >> The int pointer is unaffected, but the first line now turns from a >> function returning a pointer, to a pointer to a function! > > Of course. Randomly adding parentheses into some syntax may alter the > meaning. I really don't think that needs an exclamation mark. I get > that you don't like the syntax, but this most recent objection to it -- > that it is not immune to the insertion of key syntactic elements -- is > just daft. No, it's the syntax that's daft, and that's a fact, not just my opinion (even cdecl.org calls it 'gibberish'). Because is not taking a+b*c and turning it into (a+b)*c. It's more like turning it into (a)+b*c and the meaning changing completely, when 'a' is a function, and staying exactly the same when 'a' isn't a function. And if you do write the parentheses the correct way so that the meaning is unchanged (with the parameter list inside), then even respectable compilers such DMC don't understand it. Given that C is what it is and isn't going to change, then we have live with it. That can include writing external tools to make sense of it (cdecl), or using translators to allow C to be created via a saner syntax (as I do). But any syntax where a*b can mean a product of two values, /or/ declare b as a pointer to type a, can only be called daft. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-04-26 12:38 -0700 |
| Message-ID | <ccf625a2-ad1d-4d7c-99c8-5560e1ceb6e4@googlegroups.com> |
| In reply to | #61152 |
On Sunday, April 26, 2015 at 7:27:30 PM UTC+1, Bart wrote: > On 26/04/2015 13:40, Ben Bacarisse wrote: > > But any syntax where a*b can mean a product of two values, /or/ declare > b as a pointer to type a, can only be called daft. > It's a bit of a double take when coming to C for the first time. But it's something you quickly get used to.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-26 22:26 +0100 |
| Message-ID | <mhjl4q$d82$1@dont-email.me> |
| In reply to | #61157 |
On 26/04/2015 20:38, Malcolm McLean wrote: > On Sunday, April 26, 2015 at 7:27:30 PM UTC+1, Bart wrote: >> On 26/04/2015 13:40, Ben Bacarisse wrote: >> >> But any syntax where a*b can mean a product of two values, /or/ declare >> b as a pointer to type a, can only be called daft. >> > It's a bit of a double take when coming to C for the first time. > > But it's something you quickly get used to. Not for me. Maybe I came to C too late, but even then I could get used to = and == and even typing semicolons and other punctuation everywhere without too much problem if I was writing a lot of C code. But type declarations I can never get used to and it's the sort of thing I would rebel against because it's such an obviously bad way to go about it. It doesn't help that before C I'd spent years using (IMO) far superior left-to-right syntax for these things so I would naturally be more critical. And most people who have to use C probably aren't in a position to switch language, build syntax wrappers, or superimpose some different language on top. (TBF, complex type-specs are rare enough that they are not a reason by themself to do any of that. But when they come up, they can be nuisance to write correctly or to decipher.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-04-26 12:41 -0700 |
| Message-ID | <87a8xuhe3i.fsf@kst-u.example.com> |
| In reply to | #61152 |
Bartc <bc@freeuk.com> writes:
[...]
> No, it's the syntax that's daft, and that's a fact, not just my
> opinion (even cdecl.org calls it 'gibberish').
No, it's your opinion. The fact that others happen to share that
opinion doesn't make it a "fact".
I agree with you that C syntax is unnecessarily confusing. But it's
entirely well-defined and consistent, and quite frankly whining
about it isn't going to help.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.lists@bsb.me.uk> |
|---|---|
| Date | 2015-04-27 01:53 +0100 |
| Message-ID | <87pp6q1jek.fsf@bsb.me.uk> |
| In reply to | #61152 |
Bartc <bc@freeuk.com> writes: > On 26/04/2015 13:40, Ben Bacarisse wrote: >> Bartc <bc@freeuk.com> writes: >> <snip> >>> Also, there is this example: >>> >>> int *fred(int); // prototype for above >>> int *ptr; // pointer to int >>> >>> If I add parentheses around the *name parts: >>> >>> int (*fred)(int); >>> int (*ptr); >>> >>> The int pointer is unaffected, but the first line now turns from a >>> function returning a pointer, to a pointer to a function! >> >> Of course. Randomly adding parentheses into some syntax may alter the >> meaning. I really don't think that needs an exclamation mark. I get >> that you don't like the syntax, but this most recent objection to it -- >> that it is not immune to the insertion of key syntactic elements -- is >> just daft. > > No, it's the syntax that's daft, and that's a fact, not just my > opinion (even cdecl.org calls it 'gibberish'). I agree that the option is held by others but I'd expect more than you offer to accept it as a fact > Because is not taking a+b*c and turning it into (a+b)*c. It's more > like turning it into (a)+b*c and the meaning changing completely, when > a' is a function, and staying exactly the same when 'a' isn't a > function. Not at all. You marvel that int (*f)() and int *f() are entirely different declarations because you pretend not to know that *, (...) and [...] act like type operators with postfix operators binding more tightly than prefix ones. Do you marvel that (*f)() and *f() are different expressions? <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-26 13:24 +0100 |
| Message-ID | <mhilbf$dfm$1@dont-email.me> |
| In reply to | #61123 |
On 26/04/2015 11:17, Bartc wrote:
> On 26/04/2015 10:19, Johannes Bauer wrote:
>> On 25.04.2015 14:19, Bartc wrote:
>>> How fast can you spot the problem in this code:
>>>
>>> *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int
>>> (*))((char*)y+8));
>>
>> Since you already solved the mystery, I've got an unrelated question. Is
>> there a reason why the code generate puts the "*" in braces for "int
>> (*)"? I'm guessing there is, but I can't figure it out on the top of my
>> head.
>
> You mean, in parentheses?
>
> This is just my algorithm for converting an internal representation of
> the type into C type-spec syntax. It was easier to put the parentheses
> in everywhere than to try and figure out where they can be omitted.
>
> But I suppose I can suppress them in the simplest of cases such as the
> above.
Actually, even then I can't always leave them out:
(int *[])p;
apparently doesn't mean the same as:
(int (*)[])p;
The "()" around the "*" are added or suppressed before it knows this
will be an array element type. So it's best to just leave them in.
Exactly why * is not the same as (*), I've no idea, and I don't want to
know either; once this project is over I can forget about C type syntax
for good I hope, because it is completely crazy.
(I don't think that (int *[]) is the equivalent of ((int *)[]) because
that's a syntax error. Unless (int *) is the default but just not
allowed to be specified in the syntax.)
--
Bartc
> (AFAIK this doesn't affect the resulting code in any way. But converting
> field selections to casts and offsets may be affecting code optimisation
> so I will try and tidy that up.)
>
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-04-26 07:01 -0700 |
| Message-ID | <kfnmw1vouoe.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #61077 |
Bartc <bc@freeuk.com> writes: > How fast can you spot the problem in this code: > > *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); > > It was somewhat harder for me as the > compiler says nothing about it until the > next function dozens of lines later and > then it picks on something totally > unrelated. This code is program-generated, yes? You might want to run the output through a formatter before compiling it - that would make problems like this much easier to diagnose.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-04-26 19:55 +0100 |
| Message-ID | <mhjca2$amb$1@dont-email.me> |
| In reply to | #61135 |
On 26/04/2015 15:01, Tim Rentsch wrote: > Bartc <bc@freeuk.com> writes: > >> How fast can you spot the problem in this code: >> >> *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); >> >> It was somewhat harder for me as the >> compiler says nothing about it until the >> next function dozens of lines later and >> then it picks on something totally >> unrelated. > > This code is program-generated, yes? You might > want to run the output through a formatter before > compiling it - that would make problems like this > much easier to diagnose. > The code generator already has to function as a formatter of sorts, and I make sure it's indented correctly and braces are used consistently. However the viewer I use doesn't highlight /*...*/ comments unless they start a line, otherwise it might have been more obvious. (Although I'm already inured to C code being highlighted as a comment half-way across a line because it thinks C's ! or != operator "!" starts a comment.) But what I was more astonished at was this glaring hole in the language where "/*" starts a comment even though it can also form part of a legal expression. I was aware of a similar problem with // comments but not /*...*/ ones. It's obvious now of course. (Maybe I should added a few more parentheses...) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2015-04-27 02:39 -0500 |
| Message-ID | <hsprjahtp1fts5vjb5inpdbgh5q1r9d84c@4ax.com> |
| In reply to | #61155 |
On Sun, 26 Apr 2015 19:55:59 +0100, Bartc <bc@freeuk.com> wrote: >On 26/04/2015 15:01, Tim Rentsch wrote: >> Bartc <bc@freeuk.com> writes: >> >>> How fast can you spot the problem in this code: >>> >>> *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); >>> >>> It was somewhat harder for me as the >>> compiler says nothing about it until the >>> next function dozens of lines later and >>> then it picks on something totally >>> unrelated. >> >> This code is program-generated, yes? You might >> want to run the output through a formatter before >> compiling it - that would make problems like this >> much easier to diagnose. >> > >The code generator already has to function as a formatter of sorts, and >I make sure it's indented correctly and braces are used consistently. > >However the viewer I use doesn't highlight /*...*/ comments unless they >start a line, otherwise it might have been more obvious. (Although I'm >already inured to C code being highlighted as a comment half-way across >a line because it thinks C's ! or != operator "!" starts a comment.) > >But what I was more astonished at was this glaring hole in the language >where "/*" starts a comment even though it can also form part of a legal >expression. I was aware of a similar problem with // comments but not >/*...*/ ones. It's obvious now of course. > >(Maybe I should added a few more parentheses...) A simpler solution would be to have your code generator generate all tokens with an extra trailing space.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-04-28 08:34 -0700 |
| Message-ID | <kfnwq0wclnb.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #61155 |
Bartc <bc@freeuk.com> writes: > On 26/04/2015 15:01, Tim Rentsch wrote: >> Bartc <bc@freeuk.com> writes: >> >>> How fast can you spot the problem in this code: >>> >>> *(int (*))((char*)sptr+8)=(*(int (*))((char*)x+8)/*(int (*))((char*)y+8)); >>> >>> It was somewhat harder for me as the >>> compiler says nothing about it until the >>> next function dozens of lines later and >>> then it picks on something totally >>> unrelated. >> >> This code is program-generated, yes? You might >> want to run the output through a formatter before >> compiling it - that would make problems like this >> much easier to diagnose. > > The code generator already has to function as a formatter of > sorts, and I make sure it's indented correctly and braces are used > consistently. [snip] The point of using an external formatter is that it would be stable and debugged, and not depend on the correctness of what you're developing for it to do the right thing. Even something as simple as a filter that strips out comments could be useful.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web