Deutsch   English   Français   Italiano  
<vbepcb$q6p2$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!3.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Bart <bc@freeuk.com>
Newsgroups: comp.lang.c
Subject: Re: Top 10 most common hard skills listed on resumes...
Date: Fri, 6 Sep 2024 12:34:34 +0100
Organization: A noiseless patient Spider
Lines: 169
Message-ID: <vbepcb$q6p2$1@dont-email.me>
References: <vab101$3er$1@reader1.panix.com> <valrj7$367a8$2@dont-email.me>
 <87mskwy9t1.fsf@bsb.me.uk> <vanq4h$3iieb$1@dont-email.me>
 <875xrkxlgo.fsf@bsb.me.uk> <vapitn$3u1ub$1@dont-email.me>
 <87o75bwlp8.fsf@bsb.me.uk> <vaps06$3vg8l$1@dont-email.me>
 <871q27weeh.fsf@bsb.me.uk> <20240829083200.195@kylheku.com>
 <87v7zjuyd8.fsf@bsb.me.uk> <20240829084851.962@kylheku.com>
 <87mskvuxe9.fsf@bsb.me.uk> <vaq9tu$1te8$1@dont-email.me>
 <vbci8r$1c9e8$1@paganini.bofh.team> <vbcs65$eabn$1@dont-email.me>
 <vbekut$1kd24$1@paganini.bofh.team>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 06 Sep 2024 13:34:36 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="65207103517559065843f2ba43b77097";
	logging-data="858914"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1/K0PXdPauJDs2LuroZ/+9x"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:uUYDA5RCPHUvWAP0QQqH86FvsFY=
In-Reply-To: <vbekut$1kd24$1@paganini.bofh.team>
Content-Language: en-GB
Bytes: 7571

On 06/09/2024 11:19, Waldek Hebisch wrote:
> Bart <bc@freeuk.com> wrote:

>> If you've followed the subthread then you will know that nobody disputes
>> that assignment reads from side of '=' and writes to the other.
> 
> I dispute this and I think that to same degree several other folks too.
> Assgmenet _does not read_, it "only" writes.  Assigment get two
> parameters which are treated in different way.  Imagine that you
> are programming in a language like C, but are forbidden to use
> assignment operator.  But fortunately you have C "function"
> 'assign' with prototype:
> 
> void assign(int * p, int v);
> 
> Instead of writing
> 
>      A = B
> 
> you need to write
> 
>      assign(&A, B)

> Of course, in real life nobody is going to force you to anything,
> but except for fact that in C assignment has value the 'assign'
> function is doing the same thing as '=' operator.  And you can
> see that it is asymetric: first agrument is an addres and right
> is a value.

If you have to use a function, yes. Because you've introduced an 
artificial split in Where and When those dereferences are done.

With A=B they can be done at about the same time and the same place.

With ASSIGN(), the B dereference is done at the call-site; the A 
deference is done inside ASSIGN(), so you are obliged to pass an 
explicit reference to A. While B has already been dereferenced and you 
have its value to pass.

(You can balance it out by by requiring ASSIGN(&A, &B)!)


>> If A is in memory then it could be the same on 2-address architectures:
>>
>>      mov [A], [A]
>>
>> but more typically it needs two instructions (here using RTL):
>>
>>     mov R, [A]
>>     mov [A], R
>>
>> Here, [A] appears in both instructions, it means the same thing, and
>> refers to the same location. Only the position (left vs. right operand,
>> exactly the same as in A = A) tells you if it's reading or writing.
>   
> You somewhat miss fact that "A = B" has 3 parts, that is "A", "=", and "B".
> The second 'mov' instruction came from "=", the first 'mov' is extra.
> So instructions look symmetric, but clearly assigment part is asumetric.

Here is A:=B from my HLLs in one of my ILs (intermediate language):

     load  B
     store A

That was stack-based; here it is in 3-address-code IL:

     a := b         # more formally, 'move a, b'

This is it in dynamic byte-code:

     push B
     pop  A

In every case, both A and B operands have the same rank and the same 
levels of indirection. Only the opcode and/or operand position indicates 
if a read or write operation is performed.

>> There is a Load on one operand and a balancing Store on the other. Two
>> loads or two stores would not make sense here.
> 
> Again: only store comes from assignment.  This is clearly visible
> if instead of misleading "A = A" you take "A = B" and replace
> 'B' by various things.  Assigment part (store instruction) stays
> the same, compution of value changes.  In
> 
> A = c  + d

This has been covered. The syntactical symmetry is that whatever you 
have on the LHS, you can write the same thing on the RHS:

     A[i+1].m = A[i+1].m

Obviously, you can have RHS terms that cannot appear on the left, like 
'42', but that's usually due to separate constraints of the language. 
(C's grammar allows 42 on the LHS of '=' for example).


> 
> you get two load (for c and d) and then addition.  To put it
> differently, you have
> 
> compute value of B
> compute address of A
> store

Why don't you need to compute the address of B? Why don't you need to 
load the value of B? It is more like this:

   compute address of B
   load value of B via that address to some temporary location
   compute address of A
   store new value of A via that address

The only asymmetry in all my examples has been between Load/Store; 
Push/Pop; or positional as in Left/Right.

The mechanism for EITHER reading or writing the value of an object via 
its reference is the same; only the direction of data movement is the 
parameter.

>> Note that Load and Store can also be considered symmetric: each Load
>> reads data from somewhere and writes it somewhere else. Just like Store
>> does. So some instruction sets use the same mnemonic for both.
> 
> Concerning instruction, sure.  But load is not an assignment.
> It may look so in simple misleading cases.

In my PUSH B example from interpreted code, it will read B from memory, 
and write it to a stack (also in memory). POP A will read from the 
stack, and write to memory.

So both operations are really memory-to-memory.

>  But even if 'A' is
> allocated to register and you translate whole "A = B" to single
> load, the load computes value of 'B' and if the result is in
> correct register the assigment proper can be optimised to no
> operation.

I've done this stuff at the chip level (writing into an 8-bit latch for 
example, then reading from it); it's going to take a lot to convince me 
that this is anything much different from a read/write or direction flag!

In more complicated cases in languages, then some asymmetry does come 
up. For example, suppose C allowed this (my language allows the equivalent):

    (c ? a : b) = x;

So this assigns to either a or b depending on c. My implementation 
effectively turns it into this:

    *(c ? &a : &b) = x;

So using explicit references and derefs. However, that is internal. The 
symmetry still exists in the syntax:

    (c ? a : b) = (c ? a : b);


>> And /my/ point was that in virtually every HLL, that dereference to turn
>> a variable's address, denoted by its name, into either a read or write
>> access of its value, is implicit.
> 
> I partially agree.  Normal case is that write access is explicit
> (for example via '=' in C) and it simly takes variable address.  Only
> read access in implicit.
Well, you need /something/ to denote whether you are reading or writing 
some location.