2

My understanding is that if a pointer points to something that is read and written, that is, "inout" then, by definition it cannot be "const" (because of "out") yet, there are prototypes in the C headers that specify parameters as "inout const" which doesn't make sense to me. For intance:

EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTEnumAdapters2(_Inout_ CONST D3DKMT_ENUMADAPTERS2*);

As I mentioned above, I don't see how the parameter can be "const" given that it's also "out".

Am I misunderstanding something or is that definition incorrect ?

Thank you for your help.

`

Gerhardh
  • 11,688
  • 4
  • 17
  • 39
ScienceAmateur
  • 521
  • 4
  • 11
  • The pointed-to-value is const, not the pointer itself. this might help: https://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-and-int-const – Raildex Feb 22 '22 at 06:35
  • @Raildex, now that you mention it, I'd read that as specifying that the pointer is constant but what it points to is "inout". – ScienceAmateur Feb 22 '22 at 06:44
  • @Raildex true, but the pointer itself cannot be modified inside the function as it is passed by value. – Gerhardh Feb 22 '22 at 07:16
  • Looks like an error in the documentation and/or header, to me, because the `NumAdapters` member of the passed (pointed-to) structure **is modified** by the function. – Adrian Mole Feb 22 '22 at 13:05
  • @AdrianMole that's what I think too. The structure is modified (inout), therefore it cannot be "const" – ScienceAmateur Feb 22 '22 at 13:17
  • @ScienceAmateur: The fact that a parameter is a pointer to a `const` object does not mean the function may not or cannot modify the object. The `const` qualifier was a late addition to C and serves as little more than advice and an aid against accidental modifications. If an object was originally defined with `const`, then a function may cast a `const` pointer to it to a non-`const` pointer to it and use the new pointer to modify the object, and this behavior is defined by the C standard. – Eric Postpischil Feb 22 '22 at 13:57

1 Answers1

2

In theory, there is nothing to prevent an argument declared as _Inout_ having the const qualifier, when that argument is a pointer to a structure.

For instance, the argument in the call to D3DKMTEnumAdapters2 is a pointer to a D3DKMT_ENUMADAPTERS2 structure, which is defined as follows:

typedef struct _D3DKMT_ENUMADAPTERS2 {
  ULONG              NumAdapters;
  D3DKMT_ADAPTERINFO *pAdapters;
} D3DKMT_ENUMADAPTERS2;

Now, if the pAdapters member were a pre-allocated array of D3DKMT_ADAPTERINFO objects (of size specified in the NumAdapters member), and all the function did was to fill that data array with the relevant information for each adapter, then the passed structure itself would not have been modified – so there is no conflict with the const qualifier on the argument.

However, from the documentation for D3DKMTEnumAdapters2, it appears that the NumAdapers member itself is also changed (potentially):

When D3DKMT_ENUMADAPTERS2::pAdapters is null, D3DKMT_ENUMADAPTERS2::NumAdapters is set to the maximum supported adapter count. Callees will commonly invoke the method, first, to retrieve the maximum supported adapter count.

Thus, according to that paragraph, the const attribute will be violated when the function is called with a NULL value for the pAdapters member of the passed (pointed-to) structure.


Note that the linked documentation also implies that the NumAdapters member is modified, even when a non-null pAdapters value is given (emphasis mine):

Caller passes in array size and empty array space. Callee verifies enough room in the array, fills out array, and passes back how much of the array was used.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Thank you Adrian. Everything you mentioned about the number of adapters potentially being changed is what I saw as a conflict with the "const" specifier. IOW, I think that for that function, the "const" is not "appropriate" (to put it that way) – ScienceAmateur Feb 22 '22 at 14:10