3

In my case, I have two layers say core layer and application layer. Application layer depends of core layer.

I want that only core layer should use CRT functions.

In application layer, if any CRT function is used, it should not compile.

Is there any way to achieve this? For example, direct call to free/malloc should not be made in application layer.

One way which I thought to #define all CRT functions to some error so that Application layer cannot use direct CRT calls (Application layer is including the header files of core layer).

doptimusprime
  • 9,115
  • 6
  • 52
  • 90
  • Why would you want to do that? – Jan Hudec Nov 09 '12 at 12:44
  • You can't do it in a portable (and nice) way. Which compiler are you using? You can't #define **every** CRT function but you can **ask** them to do not use it... – Adriano Repetti Nov 09 '12 at 12:45
  • 3
    Maybe you should talk to your developers how they all should allocate memory using the core layers interface only, rather than invent barriers that hamper their work. – hansmaad Nov 09 '12 at 12:47
  • @Adriano I know it cannot be done in a portable way. Currently, I need it for Windows. Compiler is Cl (Visual Studio 2008). – doptimusprime Nov 09 '12 at 12:48
  • @JanHudec Because, I do not want developer at application layer to use direct CRT calls. Core layer is a DLL and CRT is statically linked to it. If application layer uses CRT, then there could be a problem. – doptimusprime Nov 09 '12 at 12:49
  • 2
    Code review, and a big stick. – Rook Nov 09 '12 at 12:50
  • @hansmaad Developers can be taught but cannot be stopped unless there is some mechanism to stop it. Developers are in other team/department. – doptimusprime Nov 09 '12 at 12:50
  • if both teams use CRT...WHY you have to statically link? Anyway which problems you think about if you use the same version of CRT? (by the way take a look to this: http://stackoverflow.com/questions/3807505/c-c-overriding-default-functions) – Adriano Repetti Nov 09 '12 at 12:52
  • CRT is the "standard" library... most major functions will be portable. I tend to agree you shouldn't attempt to restrict it, and doing so would be really messy. – mark Nov 09 '12 at 12:52
  • @Adriano There would not be any problem with same version of CRT but with different copies of CRT. http://msdn.microsoft.com/en-us/library/ms235460(v=vs.90).aspx – doptimusprime Nov 09 '12 at 12:55
  • 2
    @dbasic You want to STOP your developers? You assume your developers to be lazy and incompetent. I think your organsiation has a bigger problem in management style than in coding style :-) If you communicate and discuss such design decisions together with the whole team, they will very likely accept and comply with these rules. – hansmaad Nov 09 '12 at 13:02
  • Inventing barriers? That's not C++. But if you wish, you can enforce a namespace upon users of your library that would include most of the CRT functions with an incompatible parameter. It'll make sure they get a compilation error at some point, but would leave a choice. – ActiveTrayPrntrTagDataStrDrvr Nov 09 '12 at 13:03
  • @hansmaad this can and will happen incidentally in any project large enough – SomeWittyUsername Nov 09 '12 at 13:04
  • 1
    @dbasic in that case the **problem** is not with CRT functions but the **API you expose** (and the statically linked CRT too, why?) that accepts potentially dangerous parameters. You can't and you shouldn't force consumers of your library to something because of an implementation detail (static libraries). If you **need** it then hide everything inside your library and let them use whatever they want. – Adriano Repetti Nov 09 '12 at 13:09
  • 1
    @dbasic: Basically, you want to avoid DLL-hell and everything connected to that plus any dependency to CRT. There are many things we would like to live without but to restrict the usage of standard library because of your fears would be unbelievably bad idea. – SChepurin Nov 09 '12 at 13:47

2 Answers2

1

You don't need to #define all the funcs in CRT. It's enough to define one of the funcs declared in the header to cause compilation failure.

Also, look into the CRT headers, most of them rely on some construct of this kind:

    #ifndef "some unique id"
    #define "some unique id"
    /* header body */
    #endif

If you define this unique id, you'll effectively cause the header not to be included, thus compilation error will occur when trying to use function declared in this header.

holgac
  • 1,509
  • 1
  • 13
  • 25
SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85
1

Assuming all your projects are native C or C++, I believe removing the references to the windows CRT binaries should suffice. If anyone tries to use them, they'll get link errors.

For a dll, open the project properties (from Visual Studio), then go to Configuration Properties->Linker->Input and set Ignore All Default Libraries to Yes (/NODEFAULTLIB). Right above that one, set Additional Dependencies to just the libraries from your solution that you need.

For a static library, go to Librarian->General and do the same.

dario_ramos
  • 7,118
  • 9
  • 61
  • 108
  • Good idea! Requires the code to be in different projects, but this is probably the case here and if not it should be – SomeWittyUsername Nov 09 '12 at 13:00
  • 1
    This will break the `/GS` options which add buffer-checking calls to your code. The implementations of the buffer checks are in the CRT. You have similar issues with the code to call global ctors; that too is done from CRT code. – MSalters Nov 09 '12 at 14:59
  • Didn't know that. So, if you remove all references to the CRT, code will compile but those runtime checks won't be done? And what would happen with global constructors? If they cannot be called, the code shouldn't even compile. Looks like very bad design to me. These kind of things should be implemented by the compiler, not the CRT. – dario_ramos Nov 09 '12 at 15:23
  • @dario_ramos: The instrumentation added will cause a link error if you omit the CRT (since they're just unresolved function calls). The global ctors could be called; the compiler did put them in the .obj file after all. But you decided to leave out the caller, how could the compiler foresee that? Note that the compiler CANNOT implement it, since these actions are effectively done at linker scope. – MSalters Nov 09 '12 at 15:39
  • Makes sense. So, my answer to the question would work, but it would force the OP to disable the /GS buffer checks, and he would also have to call the global constructors manually somehow, or not use global constructors at all. Is that right? – dario_ramos Nov 09 '12 at 16:00