I can not understand the source of C and it does not compile in GCC, but in Visual C ++

In GCC, I got the following error:

aes.c: In the function 'copy_block:
aes.c: 278: error: lvalue required as an increment operand
aes.c: 278: error: lvalue is required as an increment operand

This is a piece of code:

static void copy_block( void * d, void *s, uint_8t nn ) { while( nn-- ) *((uint_8t*)d)++ = *((uint_8t*)s)++; } 

I tried to change it to a compiled version, but, unfortunately, for me as a Java programmer, it is unclear what actually happens here.

Maybe someone has an idea how I can change the source that it compiles into GCC, or someone has an idea of โ€‹โ€‹what is going on in detail here. It seems strange to me with dereferencing the value of the left hand, but somehow it works fine in Visual C ++.

This is a small inherited program that I have to connect to a Linux machine.

Thank you for your help.

+4
source share
7 answers

Try the following:

 #include <string.h> static void copy_block( void * d, void *s, uint_8t nn ) { memcpy(d, s, (size_t)nn); } 

What is being done is not good.

+6
source

This should do it:

 static void copy_block(void *d, void *s, uint_8t nn) { uint_8t *ud = (uint_8t *)d; uint_8t *us = (uint_8t *)s; while (nn--) { *ud = *us; ++ud; ++us; } } 

It is also much readable.

+5
source

This is some serious hairy code. There seems to be a problem with priority rules in subexpressions * (pointer) ++. (that Visual C ++ assumes it's somewhere between a miracle and an error). This seems to be just a (terrible) reimplementation of memcpy, so I suggest you use the standard version:

memcpy(d, s, nn);

I suggest doing a quick performance test in Visual C ++ to make sure that two versions of the code really do the same thing (as they appear). You can rely on some kind of fancy extreme case in the compiler.

+3
source

The problem is that casts return rvalues, but you are trying to auto-increment on the pointer returned by the application. Try the following:

 uint8_t *da = d, *sa = s; while(nn--) *da++ = *sa++; 

Two other notes:

  • nn will probably be much larger than uint8_t and probably should be size_t .
  • With this change, this function is called memcpy and is found (perhaps more efficiently) in your standard library (in string.h I suppose).
+3
source

Why does everyone suggest that you should always use library functions whenever possible?

On systems with a high degree of integrity, you want to avoid library functions such as value, because as soon as you include the library header, you should check all the source code inside it, making sure that this is a mistake. Checking the whole string.h and running it using static analyis tools, etc. Not a fun task.

For all non-PC programmers, you can use a version compatible with MISRA-C: 2004.

 void gpfunc_memcpy (void* s1, const void* s2, uint16 n) { uint8* u_s1 = (uint8*) s1; const uint8* u_s2 = (const uint8*) s2; while(n != 0) { *u_s1 = *u_s2; ++u_s1; ++u_s2; --n; } } 
+2
source

You probably hung a bracket. You want to increase the pointer, not the dereferenced value.

 static void copy_block( void * d, void *s, uint_8t nn ) { while( nn-- ) *((uint_8t*)d++) = *((uint_8t*)s++); } 

Use memcpy as a bonus tip ... much faster!

+1
source

Must be:

 static void copy_block( void * d, void *s, uint_8t nn ) { while( nn-- ) (*((uint_8t*)d))++ = (*((uint_8t*)s))++; } 
-1
source

Source: https://habr.com/ru/post/1337756/


All Articles