English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 05 February 2023, 21:31   #21
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Indeed, I'm using 0.9h too
Great, and fast, compiler!
tygre is offline  
Old 05 February 2023, 22:06   #22
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by tygre View Post
Code:
#define GLOBALS_TASK_STACK_SIZE            65535
Arrrgh!
Ok, I admit vbcc's startup-code doesn't check that the new stack size is even. But I refuse to add extra code for something which everybody should know. An unaligned stack is deadly!
phx is offline  
Old 05 February 2023, 23:35   #23
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Lesson learned

But then, later in my code, there's another statement that causes a Guru 8000 0003 only on 68000. I don't know how to explain it, although I could fix it:

Code:
had = (struct in_addr *)he->h_addr;
ina = *(had); // This dereference causes a Guru 8000 0003 
tmp = inet_ntoa(ina);
addr.sin_addr.s_addr = inet_addr(tmp);
Would you have some idea why this particular statement crashes?

One solution is to replace all this code simply with:

Code:
memcpy(&addr.sin_addr, he->h_addr, he->h_length);
Cheers!
tygre is offline  
Old 06 February 2023, 00:32   #24
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by tygre View Post
Code:
had = (struct in_addr *)he->h_addr;
ina = *(had); // This dereference causes a Guru 8000 0003 
tmp = inet_ntoa(ina);
addr.sin_addr.s_addr = inet_addr(tmp);
Would you have some idea why this particular statement crashes?
I assume that
he
points to a
struct hostent
? Then
h_addr
is a
char
pointer, which is allowed to point to an odd address.
You cast that to a
struct in_addr
pointer, which is a structure with one 32-bit unsigned longword. Therefore dereferencing
had
lets the compiler assume it can copy a 32-bit word, which causes an alignment exception when its address is odd.
phx is offline  
Old 06 February 2023, 02:42   #25
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Sorry for the lack of details: yes, you're right, he is a struct hostent.

Thanks for the explanation!

I had copied/pasted this code from diverse sources on the Internet, and it seems(ed) legit. For my own education, how could I make it work? How could I "align" he->h_addr so that it points always to an even address? (Is that even possible?)
tygre is offline  
Old 06 February 2023, 11:20   #26
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by tygre View Post
I had copied/pasted this code from diverse sources on the Internet, and it seems(ed) legit.
No. It is not. You cannot cast any
char
-pointer to an
int
-pointer and expect to be able to read an
int
from it, without running into alignment exceptions on certain architectures.

The problem is that such an alignment exception will not happen on x86 hosts, so most people never realise they are writing bad code. That's comparable to people depending on specific compiler extensions and think other compilers are broken because they strictly follow the ISO-C standard.

It's always good to compile a source with different compilers and build it for different architectures to find all issues.

Quote:
For my own education, how could I make it work? How could I "align" he->h_addr so that it points always to an even address? (Is that even possible?)
I rarely do network coding, but I would assume that
h_addr
points to a private buffer of the TCP/IP stack. You have no influence on its alignment. It is recommended to copy the address with
memcpy()
to an
in_addr
structure. Then you can depend on proper alignment.

BTW, some compilers (including vbcc) recognise certain clib functions, like memcpy, and replace them with optimised inline code. So your memcpy-call might be translated into four inline byte-copies.
phx is offline  
Old 06 February 2023, 15:15   #27
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi Phx!

Quote:
Originally Posted by phx View Post
No. It is not. You cannot cast any
char
-pointer to an
int
-pointer and expect to be able to read an
int
from it, without running into alignment exceptions on certain architectures.

The problem is that such an alignment exception will not happen on x86 hosts, so most people never realise they are writing bad code. That's comparable to people depending on specific compiler extensions and think other compilers are broken because they strictly follow the ISO-C standard.

It's always good to compile a source with different compilers and build it for different architectures to find all issues.
Ah, thanks for your explanations!

Actually, at one point I also compiled my code with SAS/C and I had to change my code a bit to make both VBCC and SAS/C happy
I should try that again one of these days...

Quote:
Originally Posted by phx View Post
I rarely do network coding, but I would assume that
h_addr
points to a private buffer of the TCP/IP stack. You have no influence on its alignment. It is recommended to copy the address with
memcpy()
to an
in_addr
structure. Then you can depend on proper alignment.
So by memcpy'ing the structure, I'm guaranteed to have a proper alignment? Because when I declare the receiving structure, it's guaranteed to be at an even address?

Quote:
Originally Posted by phx View Post
BTW, some compilers (including vbcc) recognise certain clib functions, like memcpy, and replace them with optimised inline code. So your memcpy-call might be translated into four inline byte-copies.


Thanks!
tygre is offline  
Old 06 February 2023, 17:00   #28
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by tygre View Post
So by memcpy'ing the structure, I'm guaranteed to have a proper alignment?
No. By using memcpy you can ignore the alignment, because memcpy automatically uses the best method to copy the data and takes care of that.

Quote:
Because when I declare the receiving structure, it's guaranteed to be at an even address?
It depends on the type of the object. When you write to a 16- or 32-bit object you can be sure that an m68k compiler aligned it at an even address.

In the case of
struct in_addr
it is defined as:
Code:
struct in_addr {
        in_addr_t s_addr;
}
with
in_addr_t
being an
uint32_t
.
phx is offline  
Old 06 February 2023, 17:13   #29
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Quote:
Originally Posted by tygre View Post
So by memcpy'ing the structure, I'm guaranteed to have a proper alignment? Because when I declare the receiving structure, it's guaranteed to be at an even address?
Err... If you create an object with either automatic or static lifetime, the C compiler of course ensures that the object (and its members) are aligned properly. Also, "memcpy" copies byte arrays, and thus alignment for "memcpy" does not matter. However, the issue is that objects (e.g. "structures") that arrive over the network (or some other external source) are aligned or structured according to the host system's requirements. That is, if the "byte array" that is input to memcpy() does not reassemble a structure as laid out by the host system, then memcpy() cannot ensure that either. Long story short, you cannot exchange objects ("structures") reliably between systems by just copying their memory layout, and coying stuctures 1-to-1 on disk or over the network will in general not work. You will need to define (or use an already defined) "serialization" of such objects. In general, all you can write to disk or transmit over the network are "bytes", and "serialization" defines then how to split up objects into bytes, and how to put bytes back into objects.
Thomas Richter is offline  
Old 06 February 2023, 20:47   #30
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
if you want to read a long from char *, you can do something like that:

Code:
#include <stdio.h>

#define GetLongFromCharStar(x)                                                 \
  (((long)(*x++)) << 24L | ((long)(*x++)) << 16L | (*x++) << 8 | (*x++))

int main(int argc, char const *argv[]) {
  char foo[] = {0x01, 0x02, 0x03, 0x04, 0x05};

  char *p = foo;
  if (((int)p & 1) == 0)
    ++p;

  // int l = *((int *)p);               // this bombs
  int l = GetLongFromCharStar(p); // this does not bomb
  printf("%d (%08X) - Address: %08X\n", l, l, p);
  return 0;
}
alkis is offline  
Old 07 February 2023, 00:28   #31
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi Phx, Thomas, and Alkis!

Thank you so much for your explanations and help! Very much appreciated!
Now, this part of my code works fine, but there seems to be another problem elsewhere on Leof's config. I'll track it down...

Cheers!
tygre is offline  
Old 07 February 2023, 06:32   #32
vbc
Registered User
 
Join Date: Jan 2021
Location: Germany
Posts: 18
Quote:
Originally Posted by alkis View Post
if you want to read a long from char *, you can do something like that:

Code:
#define GetLongFromCharStar(x)                                                 \
  (((long)(*x++)) << 24L | ((long)(*x++)) << 16L | (*x++) << 8 | (*x++))
This is wrong in many ways. It causes undefined behaviour due to multiple increments of x without a sequence-point. Also, any byte with bit 7 set will clobber the result due to sign-extension.
vbc is offline  
Old 07 February 2023, 09:11   #33
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by vbc View Post
This is wrong in many ways. It causes undefined behaviour due to multiple increments of x without a sequence-point. Also, any byte with bit 7 set will clobber the result due to sign-extension.
How about this?

Code:
#define GetLongFromCharStar(x)                                                 \
  (((ULONG)(*(UBYTE *)x)) << 24L | ((ULONG)(*(UBYTE *)(x + 1))) << 16L |       \
   ((ULONG)(*(UBYTE *)(x + 2))) << 8 | ((ULONG)(*(UBYTE *)(x + 3))))
alkis is offline  
Old 07 February 2023, 12:07   #34
vbc
Registered User
 
Join Date: Jan 2021
Location: Germany
Posts: 18
Quote:
Originally Posted by alkis View Post
How about this?

Code:
#define GetLongFromCharStar(x)                                                 \
  (((ULONG)(*(UBYTE *)x)) << 24L | ((ULONG)(*(UBYTE *)(x + 1))) << 16L |       \
   ((ULONG)(*(UBYTE *)(x + 2))) << 8 | ((ULONG)(*(UBYTE *)(x + 3))))
Yes, that looks good.
vbc is offline  
Old 07 February 2023, 16:33   #35
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
PS. BTW, that my code worked on 68020+, was it just by chance or is there something with 68020+ processors that allowed it to work?
tygre is offline  
Old 07 February 2023, 17:01   #36
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
Quote:
Originally Posted by tygre View Post
PS. BTW, that my code worked on 68020+, was it just by chance or is there something with 68020+ processors that allowed it to work?
68020+ allows access to words and longs also at odd addresses, although with a performance penalty.
hooverphonique is offline  
Old 07 February 2023, 18:51   #37
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Thanks HooverPhonique!
tygre is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
68020 Bit Field Instructions mcgeezer Coders. Asm / Hardware 9 27 October 2023 23:21
Getting VBCC, Roadshow, and Posix to Play Together tygre Coders. C/C++ 4 21 February 2022 19:41
Info Ade Posix vs Vbcc Posix Library Zilog Coders. General 2 28 August 2020 13:07
68020 bitfield instructions in winuae rsn8887 support.WinUAE 14 22 November 2018 20:36
Apollo 1220 - instructions and 68020 to 68030 upgrade fc.studio support.Hardware 11 10 January 2008 20:30

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 08:00.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.67983 seconds with 14 queries