From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qk1-x72f.google.com (mail-qk1-x72f.google.com [IPv6:2607:f8b0:4864:20::72f]) by sourceware.org (Postfix) with ESMTPS id A496D3945C04 for ; Wed, 17 Feb 2021 22:05:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A496D3945C04 Received: by mail-qk1-x72f.google.com with SMTP id t63so246596qkc.1 for ; Wed, 17 Feb 2021 14:05:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=I88IIqTUaE+gFwwTMxLc6uAJ8Ydrqn+ISVF3UvnATqs=; b=qliAlS/xYmYK9FrCX7MdGZHQHdbu45AEnwMFvwPmOa/RWV45nZWUUiXM0kR5+FlPc4 uf/+7N1ZDas2eJ/C5MNUjlFHH8mN3XYveJ79Ko68TKJZTaPqU1dpe7UZeGCc7GFri5rd ajOqo2Q916r+vWb4cPfjxnQqa7WvCu8298g05iqBUoO//eu7/mdeOYFYHrBKtLVVRzSz rqKsYqfXejWRvh58O1lRVaashNPBwFzKFydOZK4XLzgEENjQhTXDBls7TvBF75LSGE+T GdZiajWzGTKD9iK/UdDa4iSxpfHEgo6p5oTgKaH6JpBur5+W6W6LKB66ZeKhKAw3NpYL qzzw== X-Gm-Message-State: AOAM5323fERbDn3HX4ul/1H09DimH7nE/lSeOwTw0RaxlMtRD9YHAY3+ SN9VSn4xKjW18+0pxBW/cJBbjUOcuO4= X-Google-Smtp-Source: ABdhPJwHxLQusm2LK1qCauHSDJy+Qd5CSw5aJwFPelGiqQ5L2Od0lIrliuGRkeUYYewmH6AvQxKKmw== X-Received: by 2002:a37:4fcf:: with SMTP id d198mr1366181qkb.277.1613599520175; Wed, 17 Feb 2021 14:05:20 -0800 (PST) Received: from [192.168.0.41] ([97.118.127.0]) by smtp.gmail.com with ESMTPSA id h12sm2140202qtp.79.2021.02.17.14.05.19 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 17 Feb 2021 14:05:19 -0800 (PST) Subject: Re: using undeclared function returning bool results in wrong return value To: Thanos Makatos , "gcc@gcc.gnu.org" References: From: Martin Sebor Message-ID: Date: Wed, 17 Feb 2021 15:05:17 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Feb 2021 22:05:21 -0000 On 2/17/21 2:05 PM, Thanos Makatos via Gcc wrote: > I run into a problem that I'm not sure whether it's a bug in my program (most likely) or something wrong with GCC (highly unlikely, I know, hence why I haven't sent this to gcc-bugs). The problem is using a function that returns a bool, defined in another source file without a declaration, and the program compiled with -O. In my test, function foo1 returns true while it should be returning false. > > Here are the files and repro: > > /* main.c */ > #include > #include > #include > > bool foo2(int); > > void main(void) { > assert(!foo2(0)); > assert(!foo1(0)); > } > > /* foo.c */ > #include > > bool foo1(int n) { > return n == 1 || n == 2 || n == 4; > } > > bool foo2(int n) { > return foo1(n); > } > > # gcc --version > gcc (Debian 8.3.0-6) 8.3.0 > # gcc main.c foo.c -O > In file included from main.c:3: > main.c: In function 'main': > main.c:9:10: warning: implicit declaration of function 'foo1'; did you mean 'foo2'? [-Wimplicit-function-declaration] > assert(!foo1(0)); > ^~~~ > # ./a.out > a.out: main.c:9: main: Assertion `!foo1(0)' failed. > Aborted > > I get the same behavior if I use char instead of bool. > > The problem goes away if: > 1. I declare foo1 in main.c (just like I do for foo2), or > 2. compile w/o -O, or > 3. use n == 3 instead of n == 4 in the return statement, or > 4. use short or int instead of bool/char. > > Am I causing undefined behavior because I'm not declaring foo1? Yes. Implicit function declarations are assumed to return int so defining one that doesn't match is undefined. If the function is defined to return a smaller type the value may be passed in only a part of a register (with the remaining bits left unchanged) and the caller will be looking at the whole thing. Martin > > Please CC me in your response, I'm not subscribed to this list. >