Prev: 10+ Java Position - St. Louis Missouri.
Next: X6809.EXE (Macro Assembler by 2500 AD) Documentation
From: Vladimir Vassilevsky on 12 Aug 2010 01:02 There is a project of many files. Some functions from some modules are called from other modules, so those functions must have a global scope. However, those functions are part of a system and they have many side effects. So those functions should be called only from the right places and at the right times. What would be the elegant way to ensure that idiots won't call the system functions just because the functions are visible? In C++, I can hide those functions into classes or namespaces, so the functions will be accessible only where it is needed. Is there a way to do something like that in C ? Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
From: David Brown on 12 Aug 2010 02:58 On 12/08/2010 07:02, Vladimir Vassilevsky wrote: > > There is a project of many files. Some functions from some modules are > called from other modules, so those functions must have a global scope. > However, those functions are part of a system and they have many side > effects. So those functions should be called only from the right places > and at the right times. > > What would be the elegant way to ensure that idiots won't call the > system functions just because the functions are visible? > > In C++, I can hide those functions into classes or namespaces, so the > functions will be accessible only where it is needed. Is there a way to > do something like that in C ? > No - AFAIK in C, it's all or nothing. The only way to avoid the functions being easily callable is to omit their declarations from the header files, or to "hide" them in extra header files. Nothing can stop users declaring them with explicit "extern" statements and calling them, however. One possible way to neaten things would be to have your module header like this: #ifndef __module_h__ #define __module_h__ #ifdef AllowSystemCalls #define SYSCALL #else // gcc has a nice __attribute__ syntax to use here // warning attribute is another option #define SYSCALL __attribute__((error("I can't let you do that, Dave"))) #endif extern void NormalFunction(void); extern void SYSCALL SystemFunction(void);
From: Jon Kirwan on 12 Aug 2010 03:04 On Thu, 12 Aug 2010 00:02:43 -0500, Vladimir Vassilevsky <nospam(a)nowhere.com> wrote: ><snip> >What would be the elegant way to ensure that idiots won't call the >system functions just because the functions are visible? > >In C++, I can hide those functions into classes or namespaces, so the >functions will be accessible only where it is needed. Is there a way to >do something like that in C ? Yes -- until I saw "elegant," above. Is a cfront style solution off the table? Jon P.S. Here's my 'dump out' which is probably NOT elegant. You linker may support features the c compiler doesn't directly provide, but where you can write a program to modify the object file to gain access. c tends to only require basic linker features, though, and the linker may not have any support for something useful. Circa 1980, c++ used to be called "c with classes" and targeted c, just fine. If cfront were available (I don't know that it is, or isn't, now), it might be able to act as a kind of pre-processor of sorts for c code that used just the class-syntax as an extension to get close. You'd just write "mostly c" and use the class method and let cfront mangle stuff for you and produce usable c -- except for the mangling which you may or may not feel strongly about. If you are fine with name mangling but no cfront is handy, you could consider writing something short and sweet to get the job done as a preprocessing step. Otherwise, if you feel strongly about only using a simple editor and c and nothing else and not interested in finding out about or using any special linker features, bypassing what the c compiler does by modifying object files before the linker step, then you are stuck with the module-local scope or the global-at-link-time scope for which c provides syntax and can do what generations have done before you -- write unique names and otherwise don't include extern statements for them in modules that shouldn't be using them. That won't control anyone else who links, though. I suppose you could consider something, not unlike a librarian of some kind, that allows you to prelink some object modules together and then strip out certain global names afterwards that you don't want publicized and supply that as a linkage unit to others. It would block them even if they tried to declare the names, then. Again, might be custom work. But there it is.
From: Peter Keller on 12 Aug 2010 04:30 David Brown <david(a)westcontrol.removethisbit.com> wrote: > On 12/08/2010 07:02, Vladimir Vassilevsky wrote: >> >> There is a project of many files. Some functions from some modules are >> called from other modules, so those functions must have a global scope. >> However, those functions are part of a system and they have many side >> effects. So those functions should be called only from the right places >> and at the right times. >> >> What would be the elegant way to ensure that idiots won't call the >> system functions just because the functions are visible? >> >> In C++, I can hide those functions into classes or namespaces, so the >> functions will be accessible only where it is needed. Is there a way to >> do something like that in C ? >> > > No - AFAIK in C, it's all or nothing. The only way to avoid the > functions being easily callable is to omit their declarations from the > header files, or to "hide" them in extra header files. Nothing can stop > users declaring them with explicit "extern" statements and calling them, > however. What about the "static" keyword? Sure, it'll only let you call the function in the file in which you defined the static function, but it'll be marked as private in the object file and you shouldn't be able to link against it extern tricks or no. If you want to share the static function across several files, you're generally out of luck. Besides, just document the library's real api, and say if you deviate from it there is no guarantee of correct behavior and you won't support them. C++ with namespaces or private member functions don't fix anything for a determined hacker. I could, outside of any legal C++ means, call private methods in a class I don't have a header file to if I wanted to and only a pointer to it. Here is an example: #include <stdio.h> #include <stdlib.h> class Foo { public: Foo() {}; ~Foo() {}; void callit(int c) { hello(c); } private: void hello(int x) { printf("Hello: %d\n", x); } }; /* gcc 4.1.2 C++ ABI C linkage call */ extern "C" { void _ZN3Foo5helloEi(void*, int); } int main(int argc, char *argv[]) { Foo f; /* normal way */ f.callit(10); /* naive method to break the 'private' protection. */ _ZN3Foo5helloEi(&f, 20); return 0; } If I cared more, I could probably deduce what the function table looks like from the object and do some void (**func)(void*, int) hackery to figure out a callable function form the class pointer. So, in reality, you should be asking: What is my threat model? If it is simply "To prevent idle stupidity", then document the API only, and don't support it if they do anything else. If it is "ensure noone can ever call into code I don't want them to" you're screwed--it is always possible. Later, -pete
From: David Brown on 12 Aug 2010 06:19 On 12/08/2010 10:30, Peter Keller wrote: > David Brown<david(a)westcontrol.removethisbit.com> wrote: >> On 12/08/2010 07:02, Vladimir Vassilevsky wrote: >>> >>> There is a project of many files. Some functions from some modules are >>> called from other modules, so those functions must have a global scope. >>> However, those functions are part of a system and they have many side >>> effects. So those functions should be called only from the right places >>> and at the right times. >>> >>> What would be the elegant way to ensure that idiots won't call the >>> system functions just because the functions are visible? >>> >>> In C++, I can hide those functions into classes or namespaces, so the >>> functions will be accessible only where it is needed. Is there a way to >>> do something like that in C ? >>> >> >> No - AFAIK in C, it's all or nothing. The only way to avoid the >> functions being easily callable is to omit their declarations from the >> header files, or to "hide" them in extra header files. Nothing can stop >> users declaring them with explicit "extern" statements and calling them, >> however. > > What about the "static" keyword? Sure, it'll only let you call the > function in the file in which you defined the static function, but > it'll be marked as private in the object file and you shouldn't be > able to link against it extern tricks or no. If you want to share > the static function across several files, you're generally out of luck. > I got the impression from the O/P that the functions had to have external linkage because they could be called from other modules, but that he wanted to make it hard to call them. If "static" was the answer, then I think Vladimir would have figured that out himself. > Besides, just document the library's real api, and say if you deviate > from it there is no guarantee of correct behavior and you won't > support them. > <snip> > > So, in reality, you should be asking: What is my threat model? > > If it is simply "To prevent idle stupidity", then document the API only, > and don't support it if they do anything else. If it is "ensure noone can > ever call into code I don't want them to" you're screwed--it is always > possible. > It's always possible to work around any technical restrictions that are put in. And clear documentation is also always important. But I think the aim here is to make it hard to break the API rules - it limits the risk of accidents by people who don't read the documentation properly, or who think they know better than the document writer. > Later, > -pete > > >
|
Next
|
Last
Pages: 1 2 Prev: 10+ Java Position - St. Louis Missouri. Next: X6809.EXE (Macro Assembler by 2500 AD) Documentation |