From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from srv01.pe82.de (unknown [IPv6:2a01:4f8:1c0c:5bed::2]) by sourceware.org (Postfix) with ESMTPS id 0C6793858C74 for ; Fri, 27 Jan 2023 13:23:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0C6793858C74 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=pe82.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=pe82.de Received: from [10.99.2.11] (p5799dbcd.dip0.t-ipconnect.de [87.153.219.205]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by srv01.pe82.de (Postfix) with ESMTPSA id 57DC07D2BE for ; Fri, 27 Jan 2023 14:23:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pe82.de; s=dkim; t=1674825834; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Ui34xSnDH1fDMVn/5i0vIRJcPuMOQ8VjorpDyITlxHE=; b=WeGwG4RQc+pgwzbdmnQfBmXKOBcK8sFbbebMBOU+d/UVsB9iJ09UPOg9HnyPvqec7W3+NQ H9Mhuvq0ZiZYoxwb9cgxbO7MxcPRolfLNxj3s5laQTSxlr+4nMsM88kikLlaUHQXQIwczT HGphPYc3liy9LBSrOCO5kak5KJYgUas= From: Pepe To: gcc-help@gcc.gnu.org Subject: Correct way to provide a C callback function nside C++ Date: Fri, 27 Jan 2023 14:23:53 +0100 X-Mailer: MailMate (1.14r5918) Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; markup=markdown Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi there, I=E2=80=99m in an ongoing discussion about whether or not one should use = extern =E2=80=9CC=E2=80=9D when defining a function that will be used as = a callback in a statically linked C library. For example: c_func.h: // =E2=80=A6 void reg_callback(void (*fn)()); // =E2=80=A6 cpp_impl.cpp: // =E2=80=A6 extern =E2=80=9CC=E2=80=9D { #include =E2=80=9Cc_func.h=E2=80=9D } // my callback function with internal linkage namespace { extern =E2=80=9CC=E2=80=9D { static void my_callback_A() { // =E2=80=A6 } } // extern =E2=80=9CC=E2=80=9D void my_callback_B() { // =E2=80=A6 } } // namespace void do_something() { reg_callback(my_callback_A); reg_callback(my_callback_B); } Both callbacks have internal linkage. Both work fine, and something like = my_callback_B is found in lots of code bases. In my opinion, using callback B is implementation defined behaviour, beca= use it is not guaranteed that C and C++ use the same calling conventions.= Therefore a function must adhere to the C calling conventions to be used= as a callback in a C library, which would be callback A. I=E2=80=99ve been trying to find something definitive for days now, but t= o no avail. Now I=E2=80=99m not sure what=E2=80=99s true or not. The coun= ter argument is the following: The compiler should know reg_callback is a= C function and make sure that a given argument would either be valid or = cause a compiler error. That sounds reasonable, so I would love to know h= ow to do it properly for future reference. Given we use gcc I was hoping = to get a definitive answer in this mailing list. Thanks a lot! Pepe