Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Is there any way to make a function local to two TUs without including it as static in both? Date: Tue, 10 Mar 2015 10:37:13 -0700 Organization: None to speak of Lines: 62 Message-ID: <874mps3gae.fsf@kst-u.example.com> References: <5bnrfahtskm5osi399eb9954bleglspe2k@4ax.com> <87lhj62bt3.fsf@kst-u.example.com> <87h9tt2afx.fsf@kst-u.example.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="c77ff4d35e33d1c939d3461ebde8dd0d"; logging-data="28648"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18PMlG1Msu2Cjo+m4UK77tA" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:KmKAtbG5jjme3pFazfy4W7+4bls= sha1:MHwQNZo+Vqa35PIDoMPjOky4DrY= Xref: csiph.com comp.lang.c:58058 Richard Heathfield writes: > On 10/03/15 14:28, Keith Thompson wrote: >> Richard Heathfield writes: >>> On 09/03/15 19:47, Keith Thompson wrote: >>>> DSF writes: >>>>> Is there any way to make a function local to two TUs without including >>>>> it as static in both? >>>> [...] >>>> >>>> You can declare it in a header, and #include that header only in those >>>> two translation units. Would tnat satisfy your requirements? >>> >>> It might, but it might not. Consider this function: >>> >>> static unsigned char uccount(void) >>> { >>> static unsigned char count; >>> return count++; >>> } >> >> I didn't suggest defining it as static. Just define it normally, >> declare it in a header, and #include that header only where it's needed. > > I thought you did, but evidently I was wrong. Once the word 'static' > is in one's head, it tends to stay there (for etymological reasons, no > doubt). Sorry about that. > > Whilst your approach is of course entirely workable in Real Life, it > doesn't prevent other TUs from accessing the function, so it doesn't > (quite) answer the OP's original question. *Nothing* can reliably prevent other translation units from accessing a function. Even if it's defined as static, you can always remove the static keyword and recompile, or you can arrange to make its address available. If it's not declared in a header, you can add your own declaration. There are no secure mechanisms in C for protecting parts of a program from other parts of the same program. It can certainly make sense, in the interests of information hiding, to make it *inconvenient* for other TUs to call a function. The question is, how far do you go to accomplish this goal? One possibility, I suppose, is to add a step to the build process (Makefile?) that detects any attempt to #include the appropriate header other than in the two permitted source files. Of course it's still easy enough to edit the Makefile. Coding standards can help -- if they're enforced and/or everyone actually follows them. I think we're making assumptions about what DSF meant by "local" (easy to do, since we all know what the word means, but we don't all mean the same thing, and the standard doesn't define or use the word in a way that's particularly helpful to the current discussion). DSF, if you're still here: What exactly do you mean by "local"? -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"