Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can SFINAE detect private access violations?

I wonder whether if i test for some member of a class and the member is private what will sfinae respond? Will it error out hard or will it say ok or will it error out in the sfinae way?

like image 394
Johannes Schaub - litb Avatar asked Jan 24 '12 08:01

Johannes Schaub - litb


2 Answers

Yes.

EDIT: C++11 Standard quote from §14.8.2 [temp.deduct]

8/ If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. [ Note: Access checking is done as part of the substitution process. —end note ]

This suggests to me that private can trigger an SFINAE error. Reading on:

Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The evaluation of the substituted types and expressions can result in side effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such side effects are not in the “immediate context” and can result in the program being ill-formed.—end note ]

The "immediate context" is not so clear to me... but it does not contradict my point :)

end of EDIT

So it seems to me that it will error out in an SFINAE way, this is further confirmed by this excerpt from Clang:

// clang/Basic/DiagnosticIDs.h:185-209

  /// \brief Enumeration describing how the the emission of a diagnostic should
  /// be treated when it occurs during C++ template argument deduction.
  enum SFINAEResponse {
    /// \brief The diagnostic should not be reported, but it should cause
    /// template argument deduction to fail.
    ///
    /// The vast majority of errors that occur during template argument
    /// deduction fall into this category.
    SFINAE_SubstitutionFailure,

    /// \brief The diagnostic should be suppressed entirely.
    ///
    /// Warnings generally fall into this category.
    SFINAE_Suppress,

    /// \brief The diagnostic should be reported.
    ///
    /// The diagnostic should be reported. Various fatal errors (e.g.,
    /// template instantiation depth exceeded) fall into this category.
    SFINAE_Report,

    /// \brief The diagnostic is an access-control diagnostic, which will be
    /// substitution failures in some contexts and reported in others.
    SFINAE_AccessControl
  };

There are special cases with regard to Access Control in the case of SFINAE.

like image 74
Matthieu M. Avatar answered Oct 16 '22 10:10

Matthieu M.


No. I am on the road and don't have a standard to quote with me, but sfinae takes places in the phase of compilation where the compiler checks if the name exists at all, and in a later phase access control takes place.

This is similar to overload resolution, where all names are considered, and a match that is private is better, but won't compile, although there is another match that would be "ok" but not private.

Addition:

Core issue 1170 says:

1170 Access checking during template argument deduction
Section: 14.8.2 [temp.deduct]
Status: FDIS Submitter: Adamczyk Date: 2010-08-03

[Voted into the WP at the March, 2011 meeting.]

According to 14.8.2 [temp.deduct] paragraph 8,

Access checking is not done as part of the substitution process. Consequently, when deduction succeeds, an access error could still result when the function is instantiated.

This mimics the way access checking is done in overload resolution. However, experience has shown that this exemption of access errors from deduction failure significantly complicates the Standard library, so this rule should be changed.

Proposed resolution (January, 2011):

Change 14.8.2 [temp.deduct] paragraph 8 as follows:

If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. [Note: Access checking is not done as part of the substitution process. —end note] Consequently, when deduction succeeds, an access error could still result when the function is instantiated. Only invalid types...

So my interpretation is that this is impossible in C++03, but C++11 made it possible.

like image 5
PlasmaHH Avatar answered Oct 16 '22 11:10

PlasmaHH