-1

In my c++ code I have defined few public and private headers. Private headers are meant to be included only by these public headers based on certain #ifdefs.

How to throw error or warning to the user if user directly includes these private headers?

too honest for this site
  • 11,417
  • 3
  • 27
  • 49
PnotNP
  • 2,891
  • 2
  • 20
  • 45
  • 1
    Possible duplicate of [How do I generate an error or warning in the C preprocessor?](http://stackoverflow.com/questions/2221517/how-do-i-generate-an-error-or-warning-in-the-c-preprocessor) – user3528438 Mar 22 '17 at 18:04
  • Generally speaking - if a header is meant to be private, it should not be delivered to the end user in the first place. If it is delivered to the user - it is a public header. – Algirdas Preidžius Mar 22 '17 at 18:05
  • Depending on the conditions allowing the inclusion of the private headers, you could put an `#if !(condition) #error #endif` in your header. – 0x5453 Mar 22 '17 at 18:05
  • 1
    Shouldn't be closed, this is not really a duplicate of the referred question, the answer by @jpo38 makes a valid point and provides instruction to other people who think of attempting this – Harald Scheirich Mar 22 '17 at 18:32

2 Answers2

4

Define some token in your public headers.

Clear it at the end of your public headers.

Test for it in your private headers.

Users can still bypass it, but cannot bypass it with a simple #include.

The warning or error generated should state what they did, and what they should do instead.

Public header:

 #pragma once
 #define IN_MY_PUBLIC_HEADER_OH_WOW

 #include "private_header.h"

 #undef IN_MY_PUBLIC_HEADER_OH_WOW

Private header:

 #pragma once
 #ifndef IN_MY_PUBLIC_HEADER_OH_WOW
 #error __FILE__ should only be included via the public headers, never directly in your code
 #endif

Select a better token name than IN_MY_PUBLIC_HEADER_OH_WOW. Do not include two __ in a row, or start with a _ followed by a capital letter to avoid conflicting with restrictions in the standard.

This prevents you from directly including a private header accidentally, but still permits you to indirectly include it via the public header.

Yakk - Adam Nevraumont
  • 235,777
  • 25
  • 285
  • 465
4

What we commonly do is separate public and private headers in different folders. Then you can decide not to give access to the end user to the private folder (by not sending it to him or by not making it be part of compiler include search path).

This requires that public headers do not include private headers (what you apparently want to do). This should always be doable if the code is well organized: public headers should use forward declarations or pimpl idiom for classes defined in private headers and only source files should include the private headers. Without that, it makes no sense to provide public headers that include private headers you don't want people to include...because they will include them anyway in the end simply by including the public ones!!

Community
  • 1
  • 1
jpo38
  • 19,174
  • 7
  • 62
  • 118