From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 51898 invoked by alias); 24 Feb 2020 21:17:25 -0000 Mailing-List: contact libc-help-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: libc-help-owner@sourceware.org Received: (qmail 51888 invoked by uid 89); 24 Feb 2020 21:17:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-6.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=H*f:sk:3768224, H*i:sk:3768224 X-HELO: us-smtp-1.mimecast.com Received: from us-smtp-delivery-1.mimecast.com (HELO us-smtp-1.mimecast.com) (207.211.31.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 24 Feb 2020 21:17:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1582579042; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ISYMyUj1hAM+uMkoo1K+Yh+Ttv/SKPlqmGzgnn2csFE=; b=iAOM9g2L7uf5/403FLFg4aJy14EAa2+RxpLliJhmSmzgSeNld4rvQDOZB86hs2Xpr8MqTj 1LsG+z3CPv/l+Up0emct6i59c/9NZ6AGc7mPvO3sm2eNvTG1nUmNUsPzngZ60GIbw1/E+M YN8bykL+qh0S9TA6k9d/05JOQYWbe8I= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-207-QU2HxVTPOtWpWvMDCbJkHA-1; Mon, 24 Feb 2020 16:17:15 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AC73D8017CC; Mon, 24 Feb 2020 21:17:13 +0000 (UTC) Received: from oldenburg2.str.redhat.com (ovpn-116-104.ams2.redhat.com [10.36.116.104]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9D91A5D9E5; Mon, 24 Feb 2020 21:17:12 +0000 (UTC) From: Florian Weimer To: Alexandre =?utf-8?Q?Fran=C3=A7ois?= Garreau Cc: libc-help@sourceware.org Subject: Re: =?utf-8?Q?malloc=E2=80=99ing?= strcat References: <25950016.Ncol2qhMyO@galex-713.eu> <1946575.pu6ZMUl000@galex-713.eu> <87o8top3cn.fsf@oldenburg2.str.redhat.com> <37682248.6cMLHQH9c6@galex-713.eu> Date: Mon, 24 Feb 2020 21:17:00 -0000 In-Reply-To: <37682248.6cMLHQH9c6@galex-713.eu> ("Alexandre =?utf-8?Q?Fran?= =?utf-8?Q?=C3=A7ois?= Garreau"'s message of "Mon, 24 Feb 2020 20:34:57 +0100") Message-ID: <87v9nvk7mx.fsf@oldenburg2.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2020-02/txt/msg00046.txt.bz2 * Alexandre Fran=C3=A7ois Garreau: > Not any more than the current standard strcat functions, which more or=20 > less behaves the same (except my macro doesn=E2=80=99t buffer overflow, a= nd is not=20 > destructive, but I could as well make a version that is destructive as=20 > well using realloc that would fail for a statically allocated first=20 > argument): > #define astrcat(a, b) strcat (realloc (a, strlen(a) + strlen (b) + 1), b) > > The most often use is to concatenate two strings at a time anyway, so it= =E2=80=99s=20 > already a big step forward to have a self contained interface, rather tha= n=20 > always repetitively calling malloc with the same arguments and often with= =20 > strcpy combined=E2=80=A6 That doesn't match what I see. After all, without garbage collection, you can't do this: astrcat (astract (a, b), c) And multi-concatenations are fairly common: >> > But I=E2=80=99m curious, what did C11 change about that? >>=20 >> It's possible to use a variadic macro and a compound literal to >> construct an array in a macro, and pass that (along with the array size) >> to the actual implementation in a function (whose name would be an >> implementation detail). > > Ohhhh, you mean the function-arg-separators commas would become arrays- > separators commas, like that? > #define astrcat(...) _astrcat((char *[]) {__VA_ARGS__, NULL}) > char * > _astrcat (char *strarray[]) > { > char * result =3D malloc(1); > size_t len =3D 1; > off_t i =3D -1; > result[0] =3D '\0'; > while (strarray[++i]) > result =3D strcat(realloc(result, len +=3D strlen(strarray[i])),=20 > strarray[i]); > return result; > } I think I wouldn't use the NULL sentinel for the reasons indicated (silent truncation after memory allocation or other failure, even under valgrind), and use sizeof ((const char *[]) { __VA_ARGS__ }) / sizeof (const char *) to compute the number of arguments, and pass that separately from the pointer. >> I don't think this could be done in a portable manner before C11. > > Why couldn=E2=80=99t a standard variadic function do? it=E2=80=99s only l= onger: > #define astrcat(...) _astrcat (__VA_ARGS__, NULL) Yes, I meant C99. Compound literals and __VA_ARGS__ were added in C99. >> > And still, why wasn=E2=80=99t a macro such as the one I presented alre= ady >> > introduced? >>=20 >> strdup was only recently added to ISO C, and POSIX is somewhat dormant >> these days. > > but there were already convenient functions before standardizations=20 > weren=E2=80=99t they? such as the scanf =E2=80=9Cm=E2=80=9D (or =E2=80=9C= a=E2=80=9D I forgot) conversion modifier,=20 > or vasprintf=E2=80=A6 right? asprintf is still a GNU extension. The m scanf modifier is only in POSIX. Thanks, Florian