Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #61986 > unrolled thread
| Started by | "James Harris" <james.harris.1@gmail.com> |
|---|---|
| First post | 2015-05-14 11:43 +0100 |
| Last post | 2015-05-24 08:11 -0700 |
| Articles | 20 on this page of 101 — 15 participants |
Back to article view | Back to comp.lang.c
Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-14 11:43 +0100
Re: Sequence points and commit to memory Richard Heathfield <rjh@cpax.org.uk> - 2015-05-14 12:02 +0100
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-14 13:39 +0200
Re: Sequence points and commit to memory Richard Heathfield <rjh@cpax.org.uk> - 2015-05-14 13:18 +0100
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-14 23:11 +0200
Re: Sequence points and commit to memory Stephen Sprunk <stephen@sprunk.org> - 2015-05-14 09:06 -0500
Re: Sequence points and commit to memory Siri Cruz <chine.bleu@yahoo.com> - 2015-05-14 08:35 -0700
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-14 10:23 -0700
Re: Sequence points and commit to memory Siri Cruz <chine.bleu@yahoo.com> - 2015-05-14 10:44 -0700
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-14 11:09 -0700
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-14 12:58 -0700
Re: Sequence points and commit to memory Morris Dovey <mrdovey@iedu.com> - 2015-05-14 16:31 -0500
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-14 17:24 -0700
Re: Sequence points and commit to memory Morris Dovey <mrdovey@iedu.com> - 2015-05-14 20:18 -0500
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-15 09:34 +0200
Re: Sequence points and commit to memory Morris Dovey <mrdovey@iedu.com> - 2015-05-15 10:18 -0500
Re: 'register' attribute (was: Sequence points and commit to memory) Morris Dovey <mrdovey@iedu.com> - 2015-05-16 01:26 -0500
Re: 'register' attribute David Brown <david.brown@hesbynett.no> - 2015-05-17 00:02 +0200
Re: 'register' attribute Morris Dovey <mrdovey@iedu.com> - 2015-05-16 19:29 -0500
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-15 09:52 -0700
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-15 13:27 -0400
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-15 10:50 -0700
Re: Sequence points and commit to memory Morris Dovey <mrdovey@iedu.com> - 2015-05-15 12:32 -0500
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-14 23:23 +0200
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-15 09:42 -0700
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-15 13:13 -0400
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-16 08:32 -0700
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-15 10:35 -0700
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-15 11:08 -0700
Re: Sequence points and commit to memory Robert Wessel <robertwessel2@yahoo.com> - 2015-05-15 16:40 -0500
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-16 08:48 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-15 21:46 +0100
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-16 08:56 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-16 19:35 +0100
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-18 09:49 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-19 09:04 +0100
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-19 08:42 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-14 22:00 +0100
Re: Sequence points and commit to memory Siri Cruz <chine.bleu@yahoo.com> - 2015-05-14 14:26 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-14 22:33 +0100
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-14 23:38 +0200
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-14 23:04 +0100
Re: Sequence points and commit to memory Stephen Sprunk <stephen@sprunk.org> - 2015-05-15 13:09 -0500
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-15 21:56 +0100
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-15 17:30 -0400
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-16 07:51 +0100
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-16 22:10 -0400
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 00:25 +0200
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-18 18:55 -0400
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 09:10 +0200
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-19 12:05 -0400
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 18:42 +0200
Re: Sequence points and commit to memory Stephen Sprunk <stephen@sprunk.org> - 2015-05-16 16:33 -0500
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 00:27 +0200
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-18 19:05 -0400
Re: Sequence points and commit to memory glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-19 00:09 +0000
Re: Sequence points and commit to memory Richard Heathfield <rjh@cpax.org.uk> - 2015-05-19 01:11 +0100
Re: Sequence points and commit to memory Tim Rentsch <txr@alumni.caltech.edu> - 2015-05-23 07:02 -0700
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-18 23:21 -0400
Re: Sequence points and commit to memory glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-19 06:25 +0000
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 08:58 +0200
Re: Sequence points and commit to memory glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-19 23:20 +0000
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-20 12:31 +0200
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-19 12:10 -0400
Re: Sequence points and commit to memory glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-19 23:24 +0000
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 09:05 +0200
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-19 08:37 -0700
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-19 12:14 -0400
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 19:02 +0200
Re: Sequence points and commit to memory Robert Wessel <robertwessel2@yahoo.com> - 2015-05-15 16:46 -0500
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-17 00:20 +0200
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-17 18:19 +0100
Re: Sequence points and commit to memory Philip Lantz <prl@canterey.us> - 2015-05-17 16:11 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-18 08:30 +0100
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-18 10:31 -0700
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-18 11:11 -0700
Re: Sequence points and commit to memory David Kleinecke <dkleinecke@gmail.com> - 2015-05-19 09:37 -0700
Re: Sequence points and commit to memory Ian Collins <ian-news@hotmail.com> - 2015-05-19 17:40 +1200
Re: Sequence points and commit to memory Morris Dovey <mrdovey@iedu.com> - 2015-05-19 01:31 -0500
Re: Sequence points and commit to memory Ian Collins <ian-news@hotmail.com> - 2015-05-19 20:38 +1200
Re: Sequence points and commit to memory Morris Dovey <mrdovey@iedu.com> - 2015-05-19 10:50 -0500
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 00:46 +0200
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 00:35 +0200
Re: Sequence points and commit to memory Robert Wessel <robertwessel2@yahoo.com> - 2015-05-15 16:42 -0500
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-16 07:58 +0100
Re: Sequence points and commit to memory Robert Wessel <robertwessel2@yahoo.com> - 2015-05-16 02:18 -0500
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-16 08:36 +0100
Re: Sequence points and commit to memory Robert Wessel <robertwessel2@yahoo.com> - 2015-05-17 04:31 -0500
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-17 18:24 +0100
Re: Sequence points and commit to memory David Brown <david.brown@hesbynett.no> - 2015-05-19 00:55 +0200
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-14 11:26 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-14 22:07 +0100
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-14 14:22 -0700
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-14 22:36 +0100
Re: Sequence points and commit to memory Tim Rentsch <txr@alumni.caltech.edu> - 2015-05-22 08:16 -0700
Re: Sequence points and commit to memory Keith Thompson <kst-u@mib.org> - 2015-05-22 11:31 -0700
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-15 00:05 -0400
Re: Sequence points and commit to memory "James Harris" <james.harris.1@gmail.com> - 2015-05-15 22:25 +0100
Re: Sequence points and commit to memory James Kuyper <jameskuyper@verizon.net> - 2015-05-15 17:56 -0400
Re: Sequence points and commit to memory Nobody <nobody@nowhere.invalid> - 2015-05-17 10:04 +0100
Re: Sequence points and commit to memory Tim Rentsch <txr@alumni.caltech.edu> - 2015-05-24 08:11 -0700
Page 2 of 6 — ← Prev page 1 [2] 3 4 5 6 Next page →
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-05-15 13:27 -0400 |
| Message-ID | <55562C90.1020309@verizon.net> |
| In reply to | #62049 |
On 05/15/2015 12:52 PM, David Kleinecke wrote: ... > Now I have seen some recent code using "register". But wouldn't the code > give the same result without the "register"s ? > > I assume there must be some efficiency gain or you wouldn't have coded > it that way. But isn't that gain an artifact of your compiler and your > hardware ? "A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined." (6..1p6) You'll get the same result with and without the register keyword only if an implementation chooses to completely ignore it - which is permitted, and a fairly popular approach. However, if an implementation does decide to pay attention to the "register" keyword, it should affect the efficiency of the resulting code. It will increase the efficiency if you use it in the right places, and it will actually reduce the efficiency if you use it in the wrong places, and which places are "right" and which are "wrong" is implementation-dependent. From what I've heard, most modern compilers do a far better job than most programmers, of deciding which variables to put in registers, so interfering in that decision making can be counter-productive. Our client requires that our delivered code NOT have any compiler-dependent parts, so I have no use for "register" - other people, who are allowed and even encouraged to write code targeted at a particular platform, may find it more useful.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-15 10:50 -0700 |
| Message-ID | <87r3qhbuhr.fsf@kst-u.example.com> |
| In reply to | #62052 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 05/15/2015 12:52 PM, David Kleinecke wrote:
> ...
>> Now I have seen some recent code using "register". But wouldn't the code
>> give the same result without the "register"s ?
>>
>> I assume there must be some efficiency gain or you wouldn't have coded
>> it that way. But isn't that gain an artifact of your compiler and your
>> hardware ?
>
> "A declaration of an identifier for an object with storage-class
> specifier register suggests that access to the object be as fast as
> possible. The extent to which such suggestions are effective is
> implementation-defined." (6..1p6)
>
> You'll get the same result with and without the register keyword only if
> an implementation chooses to completely ignore it - which is permitted,
> and a fairly popular approach.
That's not *quite* all it does. Taking the address of a
register-qualified object or specifying its alignment is a constraint
violation, so compilers can't completely ignore it. If an array object
is defined with "register", any use of it that would normally result in
an implicit conversion to a pointer has undefined behavior (a compiler
could satisfy the latter by ignoring "register").
[...]
<OT>
C++'s treatment of "register" is a bit different. Taking the address of
a register-qualified object is permitted, and the "hint" is phrased
differently. Quoting the recent N4296 draft:
A register specifier is a hint to the implementation that the
variable so declared will be heavily used. [ Note: The hint
can be ignored and in most implementations it will be ignored
if the address of the variable is taken. This use is deprecated
(see D.2). — end note ]
C++ still forbids specifying the alignment of a register-qualified
object.
</OT>
--
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 | Morris Dovey <mrdovey@iedu.com> |
|---|---|
| Date | 2015-05-15 12:32 -0500 |
| Message-ID | <mj5aj4$ih6$1@speranza.aioe.org> |
| In reply to | #62049 |
On 5/15/15 11:52 AM, David Kleinecke wrote: > On Thursday, May 14, 2015 at 2:31:31 PM UTC-7, Morris Dovey wrote: >> On 5/14/15 1:09 PM, David Kleinecke wrote: >>> Fortunately I haven't seen any software for years (except stuff >>> I dredge up from the archives) that uses "register" (or "auto"). >> >> Current example at http://www.iedu.com/Solar/LENR/Code.html = >> scroll down to qram.c and see QuadRAM() function which converts a >> linear memory address to a bank-switched address in an embedded >> system. >> >> It can be a really helpful feature. :-) >> >> -- Morris Dovey http://www.iedu.com/Solar > > Now I have seen some recent code using "register". But wouldn't the > code give the same result without the "register"s ? I don’t know. According to David, it does. As a C programmer, all I could do was write code to specify the behavior I wanted... > I assume there must be some efficiency gain or you wouldn't have > coded it that way. But isn't that gain an artifact of your compiler > and your hardware ? Always. :-) At best, 'register' is only a suggestion. If I found that I couldn’t meet requirements using the C compiler, I would be obliged to rewrite the function in assembly code, which I'd prefer not to do because C source better documents the logic (for some definition of 'better'). Fortunately, even an inefficient translation will meet requirements so, while that would be disappointing, it's not a show-stopper. -- Morris Dovey http://www.iedu.com/Solar
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-05-14 23:23 +0200 |
| Message-ID | <mj33mn$gib$1@dont-email.me> |
| In reply to | #62004 |
On 14/05/15 19:23, David Kleinecke wrote:
> On Thursday, May 14, 2015 at 8:35:28 AM UTC-7, Siri Cruz wrote:
>> In article <mj1u70$r5d$1@dont-email.me>,
>> "James Harris" <james.harris.1@gmail.com> wrote:
>>
>>> How about:
>>>
>>> u = 0;
>>> f();
>>>
>>> Is u guaranteed to have been written to memory before function f is
>>
>> No. There's nothing in the above that exposes the address of u to f, so f has no
>> legitmate way to know about u.
>>
>> extern int *v; v = &u;
>> u = 0;
>> f();
>>
>> Now the f might have access to the address of u. The compiler would need to have
>> the implementation of f at hand to see if uses any (extern int*), all the places
>> those are used, etc, to safely determine that f still does not have access to u.
>>
>> MIPS used its loader as a compiler so that it had the entire program text
>> available. It could then do this kind of global analysis.
>>
>>> called? Does f need to be in a different translation unit to force prior
>>> commits to memory (so that pointers to their values are valid)?
>>
>> If you never take the address of u, it does not need memory allocated;
>> equivalently if you declare register int u, it does not need memory allocated.
u does not necessarily need to be allocated in memory even if its
address is taken. The compiler need only generate code /as if/ it were
in memory and had an address.
For example, if you want to find the bit representation of a floating
point value, you could do this:
// Assuming 32-bit unsigned int and 32-bit float, and 8-bit char
unsigned int reppi(void) {
float f = 3.141692653f;
unsigned int u;
memcpy(&u, &f, 4);
return u;
}
The compiler can replace all that with a single constant value - nothing
needs to be put anywhere in memory.
>>
>>
>> volatile int u means that no assignment nor load can be redundant. The compiler
>> must assume some unknown process can alter u asynchronously anywhere even in the
>> execution of any instruction except an atomic load or store.
>>
>> --
>> :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
>> 'I desire mercy, not sacrifice.'
>> When is a Kenyan not a Kenyan? When he's a Canadian.
>> That's People's Commissioner Siri Cruz now. Punch!
>
> Is it proper to assume that the C virtual machine has registers?
>
The C virtual machine does not make any references to "registers", as
far as I remember. The "register" keyword is a different issue, and
merely a hint to the compiler (which is usually ignored by modern
compilers) together with the restriction that the variable's address
cannot be taken.
> Computers have been built (perhaps still are) that do not have any kind
> of cache that can be called registers.
>
Cache and registers are completely different concepts.
But it is certainly true that some cpus have been build with no (or at
least very few) registers.
> In such a machine the original question vanishes (- is trivial).
No, it does not. There may be no need for the compiler to store
anything anywhere, if the value is not used later. And it could quite
happily move the store of u to a later point (or earlier point) in the
code flow, as long as the externally visible behaviour of the program is
not changed.
>
> It seems to me that what is involved here is a question about optimization
> of the output code on particular hardware. The Standard is attempting to
> place limitations on the optimization. No harm in that but perhaps specific
> rules are not needed in light of the black box rule (the output code must
> be the same for any optimization).
>
I think by "black box" rule, you are referring to what is commonly known
as the "as if" rule. The compiler need only generate code that acts "as
if" it executed on the C virtual machine, with respect to the values and
ordering of externally visible events and data. The standard says
nothing about optimisations or limitations - the compiler is free to
generate as efficient or inefficient code as it likes as long as it acts
"as if".
[toc] | [prev] | [next] | [standalone]
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2015-05-15 09:42 -0700 |
| Message-ID | <c6064209-6e7a-4a00-872d-9016694f6cf9@googlegroups.com> |
| In reply to | #62025 |
On Thursday, May 14, 2015 at 2:23:46 PM UTC-7, David Brown wrote: > On 14/05/15 19:23, David Kleinecke wrote: > > It seems to me that what is involved here is a question about optimization > > of the output code on particular hardware. The Standard is attempting to > > place limitations on the optimization. No harm in that but perhaps specific > > rules are not needed in light of the black box rule (the output code must > > be the same for any optimization). > > > > I think by "black box" rule, you are referring to what is commonly known > as the "as if" rule. The compiler need only generate code that acts "as > if" it executed on the C virtual machine, with respect to the values and > ordering of externally visible events and data. The standard says > nothing about optimisations or limitations - the compiler is free to > generate as efficient or inefficient code as it likes as long as it acts > "as if". This the same problem I just had with gcc. That is - what, exactly, is the compiler? A modern C "compiler" pipes a C source file through tokenizer pre-processor parser optimizer assembler and the optimizer may involves more steps. In particular there are optimization that can be made regardless of the target hardward and others that are hardward dependent. As nearly as I can tell gcc has this structure - regardless of how what I called "piped" is done. To me the compiler is what I called the parser above. I would exclude even the pre-processor - but in fact I have to allow it to be part of the compiler (but that rarely matters). Proper optimization is a vast and difficult problem. I would prefer not to think of it in the same breathe as the parser. But I am still getting up to speed on these questions and I had better stop here.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-05-15 13:13 -0400 |
| Message-ID | <55562947.1010901@verizon.net> |
| In reply to | #62047 |
On 05/15/2015 12:42 PM, David Kleinecke wrote: ... > This the same problem I just had with gcc. That is - what, exactly, is the > compiler? A modern C "compiler" pipes a C source file through > tokenizer > pre-processor > parser > optimizer > assembler > and the optimizer may involves more steps. In particular there are > optimization that can be made regardless of the target hardward and others > that are hardward dependent. As nearly as I can tell gcc has this > structure - regardless of how what I called "piped" is done. > > To me the compiler is what I called the parser above. I would exclude > even the pre-processor - but in fact I have to allow it to be part of > the compiler (but that rarely matters). As far as the standard is concerned, you don't need to worry about such distinctions. All of the things you mentioned above, plus the C standard library and the linker, together constitute an "implementation" of C, and the standard only talks about implementations - it never makes distinctions between the different parts that make up a given implementation. This has the advantage of, among other things, allowing implementors to choose a radically unconventional way of dividing an implementation into its component pieces. The standard does break down translation of source code into a phases (5.1.1.2). Your "tokenizer" probably implements phases 1-3, the pre-processor probably implements phase 4, the parser probably implements phases 5-6, and part of phase 7, while the optimizer and the assembler perform the rest of phase 7. The linker implements phase 8. However, the standard very explicitly does not require that the phases be executed in order - only that the results be the same as if they were executed in that order - and most implementations of C take some advantage of that permission.
[toc] | [prev] | [next] | [standalone]
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2015-05-16 08:32 -0700 |
| Message-ID | <afd22576-6893-4642-b8d7-35e35569fdc2@googlegroups.com> |
| In reply to | #62051 |
On Friday, May 15, 2015 at 10:13:52 AM UTC-7, James Kuyper wrote: > On 05/15/2015 12:42 PM, David Kleinecke wrote: > ... > > This the same problem I just had with gcc. That is - what, exactly, is the > > compiler? A modern C "compiler" pipes a C source file through > > tokenizer > > pre-processor > > parser > > optimizer > > assembler > > and the optimizer may involves more steps. In particular there are > > optimization that can be made regardless of the target hardward and others > > that are hardward dependent. As nearly as I can tell gcc has this > > structure - regardless of how what I called "piped" is done. > > > > To me the compiler is what I called the parser above. I would exclude > > even the pre-processor - but in fact I have to allow it to be part of > > the compiler (but that rarely matters). > > As far as the standard is concerned, you don't need to worry about such > distinctions. All of the things you mentioned above, plus the C standard > library and the linker, together constitute an "implementation" of C, > and the standard only talks about implementations - it never makes > distinctions between the different parts that make up a given > implementation. This has the advantage of, among other things, allowing > implementors to choose a radically unconventional way of dividing an > implementation into its component pieces. > > The standard does break down translation of source code into a phases > (5.1.1.2). Your "tokenizer" probably implements phases 1-3, the > pre-processor probably implements phase 4, the parser probably > implements phases 5-6, and part of phase 7, while the optimizer and the > assembler perform the rest of phase 7. The linker implements phase 8. > However, the standard very explicitly does not require that the phases > be executed in order - only that the results be the same as if they were > executed in that order - and most implementations of C take some > advantage of that permission. I'm loooking at C from the point of view of a compiler writer. I want to understand what I am doing. I think you are offended by my "breezy" way of refering to the parts of the whole. Of course, the standard looks like what I said. In my view the first goal is to write as simple a compiler as possible. The pipeline view point is just a way of describing the abstract ppocedure.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-15 10:35 -0700 |
| Message-ID | <87vbftbv6r.fsf@kst-u.example.com> |
| In reply to | #62047 |
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> David Kleinecke <dkleinecke@gmail.com> writes:
>>This the same problem I just had with gcc. That is - what, exactly, is the
>>compiler? A modern C "compiler" pipes a C source file through
>
> "3.12
>
> 1 implementation
>
> particular set of software, running in a particular
> translation environment under particular control
> options, that performs translation of programs for, and
> supports execution of functions in, a particular
> execution environment"
A "compiler" is only part of an "implementation". The exact meaning of
"compiler" is unclear, but I think there's general agreement that the
linker and runtime library are not part of it.
I might *informally* refer to the process of generating an executable
from a source file as "compiling", but strictly speaking it's compiling
and linking; `gcc -c foo.c` compiles, whereas `gcc foo.c -o foo`
compiles and links.
--
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 | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-15 11:08 -0700 |
| Message-ID | <87iobtbto9.fsf@kst-u.example.com> |
| In reply to | #62047 |
David Kleinecke <dkleinecke@gmail.com> writes:
[...]
> This the same problem I just had with gcc. That is - what, exactly, is the
> compiler? A modern C "compiler" pipes a C source file through
> tokenizer
> pre-processor
> parser
> optimizer
> assembler
> and the optimizer may involves more steps. In particular there are
> optimization that can be made regardless of the target hardward and others
> that are hardward dependent. As nearly as I can tell gcc has this
> structure - regardless of how what I called "piped" is done.
The tokenizer is not typically a separate pass. There might be
something like a "get_next_token()" function that's invoked by the
parser. Furthermore, both the preprocessor and the compiler itself
generally need to perform tokenization, with different rules
("preprocessor tokens" vs. "tokens"). (Usually the output of the
preprocessor is text containing C source code; other representations are
possible, and might not require tokenization in later phases.)
In the translation phase model given in 5.1.1.2, phase 3 decomposes the
source file into preprocessing tokens, and phase 7 converts each
preprocessing token into a token. (Some valid preprocessing tokens are
not valid tokens.) The translation phases needn't correspond to
compiler passes.
Optimization isn't necessarily a distinct phase, though it can be.
Optimizations can be performed in several different parts of the
compilation process. There might be an optimization phase that
operates on some compiler-specific internal representation and
another "peephole" optimization phase that operates on machine code,
or on some representation of it.
In some compilers, there's a separate pass that translates an internal
representation to machine or assembly code; this is typically called the
"code generator" (not to be confused with tools that generate source
code).
Some compilers generate machine code directly; others generate assembly
code and invoke an external assembler.
There's More Than One Way To Do It.
> To me the compiler is what I called the parser above. I would exclude
> even the pre-processor - but in fact I have to allow it to be part of
> the compiler (but that rarely matters).
>
> Proper optimization is a vast and difficult problem. I would prefer not
> to think of it in the same breathe as the parser.
>
> But I am still getting up to speed on these questions and I had better
> stop here.
--
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 | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2015-05-15 16:40 -0500 |
| Message-ID | <alpcla1rviuvn8g0vk4tcdek1hs64d1tl1@4ax.com> |
| In reply to | #62058 |
On Fri, 15 May 2015 11:08:06 -0700, Keith Thompson <kst-u@mib.org>
wrote:
>David Kleinecke <dkleinecke@gmail.com> writes:
>[...]
>> This the same problem I just had with gcc. That is - what, exactly, is the
>> compiler? A modern C "compiler" pipes a C source file through
>> tokenizer
>> pre-processor
>> parser
>> optimizer
>> assembler
>> and the optimizer may involves more steps. In particular there are
>> optimization that can be made regardless of the target hardward and others
>> that are hardward dependent. As nearly as I can tell gcc has this
>> structure - regardless of how what I called "piped" is done.
>
>The tokenizer is not typically a separate pass. There might be
>something like a "get_next_token()" function that's invoked by the
>parser. Furthermore, both the preprocessor and the compiler itself
>generally need to perform tokenization, with different rules
>("preprocessor tokens" vs. "tokens"). (Usually the output of the
>preprocessor is text containing C source code; other representations are
>possible, and might not require tokenization in later phases.)
>
>In the translation phase model given in 5.1.1.2, phase 3 decomposes the
>source file into preprocessing tokens, and phase 7 converts each
>preprocessing token into a token. (Some valid preprocessing tokens are
>not valid tokens.) The translation phases needn't correspond to
>compiler passes.
Actually the compiler does not need to perform tokenization - the list
of tokens output from the preprocessor (and all action the
preprocessor takes is on, and results in, pp-tokens) could be input
directly to the compiler after "converting" them. In practice there
would be little or nothing to do but convert the representations as
appropriate (except possibly generating an error message if any
pp-tokens remain).
OTOH, have a text file as the result of pre-processing is quite
common, and if the compiler proper inputs that, it will, of course,
have to tokenize again.
[toc] | [prev] | [next] | [standalone]
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2015-05-16 08:48 -0700 |
| Message-ID | <a108e3db-a9c8-48ad-8491-1648896940b3@googlegroups.com> |
| In reply to | #62058 |
On Friday, May 15, 2015 at 11:08:17 AM UTC-7, Keith Thompson wrote:
> David Kleinecke <dkleinecke@gmail.com> writes:
> [...]
> > This the same problem I just had with gcc. That is - what, exactly, is the
> > compiler? A modern C "compiler" pipes a C source file through
> > tokenizer
> > pre-processor
> > parser
> > optimizer
> > assembler
> > and the optimizer may involves more steps. In particular there are
> > optimization that can be made regardless of the target hardward and others
> > that are hardward dependent. As nearly as I can tell gcc has this
> > structure - regardless of how what I called "piped" is done.
>
> The tokenizer is not typically a separate pass. There might be
> something like a "get_next_token()" function that's invoked by the
> parser. Furthermore, both the preprocessor and the compiler itself
> generally need to perform tokenization, with different rules
> ("preprocessor tokens" vs. "tokens"). (Usually the output of the
> preprocessor is text containing C source code; other representations are
> possible, and might not require tokenization in later phases.)
>
> In the translation phase model given in 5.1.1.2, phase 3 decomposes the
> source file into preprocessing tokens, and phase 7 converts each
> preprocessing token into a token. (Some valid preprocessing tokens are
> not valid tokens.) The translation phases needn't correspond to
> compiler passes.
>
> Optimization isn't necessarily a distinct phase, though it can be.
> Optimizations can be performed in several different parts of the
> compilation process. There might be an optimization phase that
> operates on some compiler-specific internal representation and
> another "peephole" optimization phase that operates on machine code,
> or on some representation of it.
>
> In some compilers, there's a separate pass that translates an internal
> representation to machine or assembly code; this is typically called the
> "code generator" (not to be confused with tools that generate source
> code).
>
> Some compilers generate machine code directly; others generate assembly
> code and invoke an external assembler.
>
> There's More Than One Way To Do It.
>
> > To me the compiler is what I called the parser above. I would exclude
> > even the pre-processor - but in fact I have to allow it to be part of
> > the compiler (but that rarely matters).
> >
> > Proper optimization is a vast and difficult problem. I would prefer not
> > to think of it in the same breathe as the parser.
> >
> > But I am still getting up to speed on these questions and I had better
> > stop here.
>
> --
> 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"
I said pipe rather than sequence because tokenizer, preprocessor and
parser can be easily piped. The paser calls a next-token from the pre-
processor which in turn calls a next-token from the tokenizer. If I were
to do no optimization I could make the code generator pipe from the
parser (but it would be better to let the parser push its output into
the code generator). But I could, if I were purist enough, have the
tokenizer write a file send that file to the preprocessor which writes
a file, etc. Perhaps for debugging.
Optimization can be done to some extent in the parser. But there is
always the suspicion that hardware bias is being built in. Some
optimizing seems to be target hardware independent and some is clearly
dependent. Optimization is a big subject. My approach is to optimize as
little as possible in the parser and make optimization a separate module
that can be studied independently.
[toc] | [prev] | [next] | [standalone]
| From | "James Harris" <james.harris.1@gmail.com> |
|---|---|
| Date | 2015-05-15 21:46 +0100 |
| Message-ID | <mj5lt1$54s$1@dont-email.me> |
| In reply to | #62047 |
"David Kleinecke" <dkleinecke@gmail.com> wrote in message news:c6064209-6e7a-4a00-872d-9016694f6cf9@googlegroups.com... ... > This the same problem I just had with gcc. That is - what, exactly, is > the > compiler? A modern C "compiler" pipes a C source file through > tokenizer > pre-processor > parser > optimizer > assembler I would say you are missing two key steps: a semantic analyser and, most important of all, a translator. The parser recognises the structure of a program. The semantic analyser checks that the program makes sense, especially in terms of using types correctly. ... > To me the compiler is what I called the parser above. I would exclude > even the pre-processor - but in fact I have to allow it to be part of > the compiler (but that rarely matters). The translator is the bit that actually creates the output program. If you like, *that* is the compiler; the prior stages are just there so that the translator can understand the input. Depending on the compiler there can be multiple translate and optimise phases interleaved. James
[toc] | [prev] | [next] | [standalone]
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2015-05-16 08:56 -0700 |
| Message-ID | <99ebf281-1c43-47cb-b7e4-84f8a85caeb5@googlegroups.com> |
| In reply to | #62067 |
On Friday, May 15, 2015 at 1:46:37 PM UTC-7, James Harris wrote: > "David Kleinecke" <dkleinecke@gmail.com> wrote in message > news:c6064209-6e7a-4a00-872d-9016694f6cf9@googlegroups.com... > > ... > > > This the same problem I just had with gcc. That is - what, exactly, is > > the > > compiler? A modern C "compiler" pipes a C source file through > > tokenizer > > pre-processor > > parser > > optimizer > > assembler > > I would say you are missing two key steps: a semantic analyser and, most > important of all, a translator. The parser recognises the structure of a > program. The semantic analyser checks that the program makes sense, > especially in terms of using types correctly. > > ... > > > To me the compiler is what I called the parser above. I would exclude > > even the pre-processor - but in fact I have to allow it to be part of > > the compiler (but that rarely matters). > > The translator is the bit that actually creates the output program. If > you like, *that* is the compiler; the prior stages are just there so > that the translator can understand the input. > > Depending on the compiler there can be multiple translate and optimise > phases interleaved. > > James Semantic analysis (in the sense I think you used the words) is surely needed. I visualized it as as aspect of parsing. But you are right - it could be done separately. I don't think it would be a good idea to separate it out - but it's possible. Isn't hat I called "assembly language" and is also called "code generation" the same as your "translate". Or do you mean changes in representation during optimization. I can see no limit on how weird as optimizer might get.
[toc] | [prev] | [next] | [standalone]
| From | "James Harris" <james.harris.1@gmail.com> |
|---|---|
| Date | 2015-05-16 19:35 +0100 |
| Message-ID | <mj82jj$ldp$1@dont-email.me> |
| In reply to | #62116 |
"David Kleinecke" <dkleinecke@gmail.com> wrote in message news:99ebf281-1c43-47cb-b7e4-84f8a85caeb5@googlegroups.com... > On Friday, May 15, 2015 at 1:46:37 PM UTC-7, James Harris wrote: >> "David Kleinecke" <dkleinecke@gmail.com> wrote in message >> news:c6064209-6e7a-4a00-872d-9016694f6cf9@googlegroups.com... >> >> ... >> >> > This the same problem I just had with gcc. That is - what, exactly, >> > is >> > the >> > compiler? A modern C "compiler" pipes a C source file through >> > tokenizer >> > pre-processor >> > parser >> > optimizer >> > assembler >> >> I would say you are missing two key steps: a semantic analyser and, >> most >> important of all, a translator. The parser recognises the structure >> of a >> program. The semantic analyser checks that the program makes sense, >> especially in terms of using types correctly. >> >> ... >> >> > To me the compiler is what I called the parser above. I would >> > exclude >> > even the pre-processor - but in fact I have to allow it to be part >> > of >> > the compiler (but that rarely matters). >> >> The translator is the bit that actually creates the output program. >> If >> you like, *that* is the compiler; the prior stages are just there so >> that the translator can understand the input. >> >> Depending on the compiler there can be multiple translate and >> optimise >> phases interleaved. >> >> James > > Semantic analysis (in the sense I think you used the words) is surely > needed. I visualized it as as aspect of parsing. But you are right - > it > could be done separately. I don't think it would be a good idea to > separate it out - but it's possible. You can only combine them if the source language can be compiled in order, i.e. by the time you see a piece of code that will result in some output you have all the information you need in order to generate the output. Even then it is not usually a good idea because you might generate some output as you parse but then find an error later in the source. Many languages require semantic checking to happen later but even if your source language does not it is usually far easier to do it separately on the tree structure that your parsing stage has produced. You can think of parsing as recognising elements which are adjacent to each other in the source. Semantic analysis usually cross-relates elements which are separated, such as declarations and uses. When you come to do optimisations you will almost always want to do them on a tree first (where the tree represents the source). > Isn't hat I called "assembly language" and is also called "code > generation" the same as your "translate". Or do you mean changes in > representation during optimization. I can see no limit on how weird > as optimizer might get. You had "assembler" which I took to mean something which would take assembly code and convert it to machine code. As you are starting simple you may find you can generate assembly language output directly from the tree that represents your source, once you have worked out the type of each expression. James
[toc] | [prev] | [next] | [standalone]
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2015-05-18 09:49 -0700 |
| Message-ID | <e951b485-9af2-4ac3-bec4-73c129a03593@googlegroups.com> |
| In reply to | #62121 |
On Saturday, May 16, 2015 at 11:35:42 AM UTC-7, James Harris wrote: > "David Kleinecke" <dkleinecke@gmail.com> wrote in message > news:99ebf281-1c43-47cb-b7e4-84f8a85caeb5@googlegroups.com... > > On Friday, May 15, 2015 at 1:46:37 PM UTC-7, James Harris wrote: > >> "David Kleinecke" <dkleinecke@gmail.com> wrote in message > >> news:c6064209-6e7a-4a00-872d-9016694f6cf9@googlegroups.com... > >> > >> ... > >> > >> > This the same problem I just had with gcc. That is - what, exactly, > >> > is > >> > the > >> > compiler? A modern C "compiler" pipes a C source file through > >> > tokenizer > >> > pre-processor > >> > parser > >> > optimizer > >> > assembler > >> > >> I would say you are missing two key steps: a semantic analyser and, > >> most > >> important of all, a translator. The parser recognises the structure > >> of a > >> program. The semantic analyser checks that the program makes sense, > >> especially in terms of using types correctly. > >> > >> ... > >> > >> > To me the compiler is what I called the parser above. I would > >> > exclude > >> > even the pre-processor - but in fact I have to allow it to be part > >> > of > >> > the compiler (but that rarely matters). > >> > >> The translator is the bit that actually creates the output program. > >> If > >> you like, *that* is the compiler; the prior stages are just there so > >> that the translator can understand the input. > >> > >> Depending on the compiler there can be multiple translate and > >> optimise > >> phases interleaved. > >> > >> James > > > > Semantic analysis (in the sense I think you used the words) is surely > > needed. I visualized it as as aspect of parsing. But you are right - > > it > > could be done separately. I don't think it would be a good idea to > > separate it out - but it's possible. > > You can only combine them if the source language can be compiled in > order, i.e. by the time you see a piece of code that will result in some > output you have all the information you need in order to generate the > output. > > Even then it is not usually a good idea because you might generate some > output as you parse but then find an error later in the source. > > Many languages require semantic checking to happen later but even if > your source language does not it is usually far easier to do it > separately on the tree structure that your parsing stage has produced. > You can think of parsing as recognising elements which are adjacent to > each other in the source. Semantic analysis usually cross-relates > elements which are separated, such as declarations and uses. > > When you come to do optimisations you will almost always want to do them > on a tree first (where the tree represents the source). > > > Isn't hat I called "assembly language" and is also called "code > > generation" the same as your "translate". Or do you mean changes in > > representation during optimization. I can see no limit on how weird > > as optimizer might get. > > You had "assembler" which I took to mean something which would take > assembly code and convert it to machine code. As you are starting simple > you may find you can generate assembly language output directly from the > tree that represents your source, once you have worked out the type of > each expression. > > James We may have different concepts of what "semantic checking" means. To me it means mostly insuring that types fit together and do not violate the operator definitions. This is easily done whenever the parse finds an action is about to be preformed. Is there more to what you call semantic analysis? As you say, it is possible to generate machine code in the parser. But it is poor practice. (1) it limits the compiler to exactly one target machine and (2) everybody wants a little optimization. PS: Not all parsers create trees. My parser creates fragments of straight line code between an entry point and one or two jumps. This is an implict directed graph where each node has one or two out links. It is easy to detect loops this way and so on during optimization.
[toc] | [prev] | [next] | [standalone]
| From | "James Harris" <james.harris.1@gmail.com> |
|---|---|
| Date | 2015-05-19 09:04 +0100 |
| Message-ID | <mjeqnf$crg$1@dont-email.me> |
| In reply to | #62225 |
"David Kleinecke" <dkleinecke@gmail.com> wrote in message news:e951b485-9af2-4ac3-bec4-73c129a03593@googlegroups.com... > On Saturday, May 16, 2015 at 11:35:42 AM UTC-7, James Harris wrote: ... > We may have different concepts of what "semantic checking" means. To > me > it means mostly insuring that types fit together and do not violate > the > operator definitions. This is easily done whenever the parse finds an > action is about to be preformed. > > Is there more to what you call semantic analysis? Yes and no. If you are compiling a language where the type definitions always precede their uses and you can work out the types of intermediate expressions as you go then you may be able to do the full translation straight away (always being aware that you might have to throw it away if you find an error in the source, that is). However, in the more general case that won't work, for example if types may be defined after their first uses appear. The comment about intermediate expressions is that even they have types which are often inferred from their operands. Those types can be worked out by working up the tree from leaves to root. To make an example, in a = c + m * x the subexpression m * x has a type which is based on the types of m and x. That type then carries into the addition, and so on. But there are lots of ways to write a compiler. Whatever works for you is good. James
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-19 08:42 -0700 |
| Message-ID | <87sias376y.fsf@kst-u.example.com> |
| In reply to | #62225 |
David Kleinecke <dkleinecke@gmail.com> writes:
[...]
> We may have different concepts of what "semantic checking" means. To me
> it means mostly insuring that types fit together and do not violate the
> operator definitions. This is easily done whenever the parse finds an
> action is about to be preformed.
>
> Is there more to what you call semantic analysis?
Yes, there's a lot more than that. Semantic analysis (is that supposed
to be distinct from "semantic checking"?) includes resolving the
meanings of identifiers, creating symbol table entries, and so forth.
It's not possible to know whether
x + y
is valid until you've determined what x and y mean.
Unlike some languages, C can't even be parsed without symbol table
information, mostly due to "typedef".
--
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 | "James Harris" <james.harris.1@gmail.com> |
|---|---|
| Date | 2015-05-14 22:00 +0100 |
| Message-ID | <mj32ad$b2p$1@dont-email.me> |
| In reply to | #62001 |
"Siri Cruz" <chine.bleu@yahoo.com> wrote in message
news:chine.bleu-804F61.08350514052015@news.eternal-september.org...
> In article <mj1u70$r5d$1@dont-email.me>,
> "James Harris" <james.harris.1@gmail.com> wrote:
>
>> How about:
>>
>> u = 0;
>> f();
>>
>> Is u guaranteed to have been written to memory before function f is
>
> No. There's nothing in the above that exposes the address of u to f,
> so f has no
> legitmate way to know about u.
>
> extern int *v; v = &u;
> u = 0;
> f();
>
> Now the f might have access to the address of u. The compiler would
> need to have
> the implementation of f at hand to see if uses any (extern int*), all
> the places
> those are used, etc, to safely determine that f still does not have
> access to u.
If u is a global or, as you point out, its address has been taken and
stored elsewhere, then the compiler would have to spill u to memory
before making the function call unless it could prove that f did not
read or write u. Putting f in another translation unit should do the
latter part. According to
http://port70.net/~nsz/c/c89/c89-draft.html#2.1.2.3
"Alternatively, an implementation might perform various optimizations
within each translation unit, such that the actual semantics would agree
with the abstract semantics only when making function calls across
translation unit boundaries. In such an implementation, at the time of
each function entry and function return where the calling function and
the called function are in different translation units, the values of
all externally linked objects and of all objects accessible via pointers
therein would agree with the abstract semantics. "
> MIPS used its loader as a compiler so that it had the entire program
> text
> available. It could then do this kind of global analysis.
>
>> called? Does f need to be in a different translation unit to force
>> prior
>> commits to memory (so that pointers to their values are valid)?
>
> If you never take the address of u, it does not need memory allocated;
> equivalently if you declare register int u, it does not need memory
> allocated.
>
>
> volatile int u means that no assignment nor load can be redundant. The
> compiler
> must assume some unknown process can alter u asynchronously anywhere
> even in the
> execution of any instruction except an atomic load or store.
In reality volatile is too strong a restriction. I don't need the values
to be read from memory each time they are referenced. I only need to
ensure that updates to them are written to memory.
In the absence of being able to code a proper memory barrier (as per
David's suggestion) volatile is a good choice.
For the moment I have chosen to make some updates in a function in a
separate translation unit with the idea that when the called function
returns across the TU boundary its updates will *have* to have been
written to memory. Example function below. In this case I had to make
two updates atomic so have added interrupt disable and restore around it
but the main point is that the updates *should* AFAICS be guaranteed to
end up in memory before the function returns. After all, there's no way
they can be kept in registers after the function ends if the compiler
has no way to do inter-function optimisation.
void dnode_delete(dnode_t *x) {
unsigned state;
/* Disable interrupts */
state = irqrx_set(IRQRX_DISABLE);
x->prev.next = x.next;
x->next.prev = x.prev;
/* Restore interrupt handling */
irqrx_set(state);
}
The code is ostentibly simple but making it robust is not!
James
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruz <chine.bleu@yahoo.com> |
|---|---|
| Date | 2015-05-14 14:26 -0700 |
| Message-ID | <chine.bleu-B4B225.14262014052015@news.eternal-september.org> |
| In reply to | #62020 |
In article <mj32ad$b2p$1@dont-email.me>, "James Harris" <james.harris.1@gmail.com> wrote: > In reality volatile is too strong a restriction. I don't need the values > to be read from memory each time they are referenced. I only need to > ensure that updates to them are written to memory. Yes, but some dubiously designed I/O hardware changes state on register load and not just register store. -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. 'I desire mercy, not sacrifice.' When is a Kenyan not a Kenyan? When he's a Canadian. That's People's Commissioner Siri Cruz now. Punch!
[toc] | [prev] | [next] | [standalone]
| From | "James Harris" <james.harris.1@gmail.com> |
|---|---|
| Date | 2015-05-14 22:33 +0100 |
| Message-ID | <mj348d$imo$1@dont-email.me> |
| In reply to | #62026 |
"Siri Cruz" <chine.bleu@yahoo.com> wrote in message news:chine.bleu-B4B225.14262014052015@news.eternal-september.org... > In article <mj32ad$b2p$1@dont-email.me>, > "James Harris" <james.harris.1@gmail.com> wrote: > >> In reality volatile is too strong a restriction. I don't need the >> values >> to be read from memory each time they are referenced. I only need to >> ensure that updates to them are written to memory. > > Yes, but some dubiously designed I/O hardware changes state on > register load and > not just register store. I know what you mean but there is no IO hardware here. This is only about getting the compiler to spill certain values to memory. What I need is not what volatile was designed for. James
[toc] | [prev] | [next] | [standalone]
Page 2 of 6 — ← Prev page 1 [2] 3 4 5 6 Next page →
Back to top | Article view | comp.lang.c
csiph-web