🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #6401

Re: gcc-2.7.1: memcpy() problems persists

#6401
From: Erkki Ruohtula
Date: Fri, 24 Nov 1995 00:00
76 lines
2595 bytes
In article <9511201916.AA29270@life.ai.mit.edu> Guertin@forsythe.stanford.edu (Dick Guertin) writes:
...
>So it is my contention that the compiler MUST honor
>the arguments of memcpy, and can only optimize on
>hardware platforms that provide instructions that
>do not violate programmer directives.

I believe that this is precisely what the standard intends, whether or not
there are any casts in the arguments! Time for some chapter and verse.
ANSI C section 4.11.2.1: "The memcpy function":

# Synopsis
#
#   #include <string.h>
#
#   void *memcpy(void *s1, const void *s2, size_t n);
#
# Description
#
# The memcpy function copies n characters from the object pointed to by
# s2 into the object pointed to by s1. If copying takes place between
# objects that overlap, the behaviour is undefined.

There is nothing about alignment restrictions: memcpy is defined in
terms of copying characters. Elsewhere (3.3.16) the standard
promises that a pointer to any type can be assigned to void*,
and the rules of parameter compatibility are defined in terms of
assignment (3.3.2.2).

I can only understand these rules to mean that even in cases where

  *a = *b;

fails because of misaligment, doing the copying using memcpy as in

  memcpy(a, b, sizeof(*a));

must not fail. Yet this is what gcc 2.7.1 does. Here is a simple
test program. On SPARC (Solbourne, OS/MP 4.1B), an executable compiled
without options will dump core after printing

start
did copy_m

which is perfectly correct behaviour, but compiled using "-O", it
only gets as far as "start".

#include <stdio.h>
#include <string.h>

void copy_a(long *dest, long *src)
{
    *dest = *src;
}

void copy_m(long *dest, long *src)
{
    memcpy(dest, src, sizeof(*dest));
}

int main(void)
{
    char buf[20];

    puts("start");
    copy_m((long *)(buf+1), (long *)(buf+11));
    puts("did copy_m");
    copy_a((long *)(buf+1), (long *)(buf+11));
    puts("did copy_a");
    return 0;
}

---
Erkki Ruohtula     / Nokia Telecommunications Oy
eru@tele.nokia.fi / P.O. Box 33 FIN-02601 Espoo, Finland
(My private opinions, of course)
Technical Details
Message-ID: <199511241109.NAA04283@tnso04.tele.nokia.fi>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 113d02,ffb1e88010d14e37
X-Google-Attributes: gid113d02,public
From: eru@tnso04.tele.nokia.fi (Erkki Ruohtula)
Subject: Re: gcc-2.7.1: memcpy() problems persists
Date: 1995/11/24
Message-ID: <199511241109.NAA04283@tnso04.tele.nokia.fi>
X-Deja-AN: 120031665
distribution: gnu
sender: daemon@cis.ohio-state.edu
organization: GNUs Not Usenet
newsgroups: gnu.gcc.bug