Skip to content

Remove the content of the contrast between inline functions and macros #4823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 13, 2023

Conversation

Mq-b
Copy link
Contributor

@Mq-b Mq-b commented Nov 21, 2023

Inline functions vs. macros

Inline functions and macros have nothing to do with each other, and this description can simply be removed.

cppreference doesn't mention macros.

Copy link
Contributor

Learn Build status updates of commit 91298f2:

✅ Validation status: passed

File Status Preview URL Details
.gitignore ✅Succeeded
docs/cpp/inline-functions-cpp.md ✅Succeeded

For more details, please refer to the build report.

For any questions, please:

@Mq-b
Copy link
Contributor Author

Mq-b commented Nov 21, 2023

@microsoft-github-policy-service agree

Copy link
Contributor

@Mq-b : Thanks for your contribution! The author(s) have been notified to review your proposed change.

@Court72
Copy link
Contributor

Court72 commented Nov 21, 2023

@TylerMSFT

Can you review the proposed changes?

When the changes are ready for publication, add a #sign-off comment to signal that the PR is ready for the review team to merge.

#label:"aq-pr-triaged"
@MicrosoftDocs/public-repo-pr-review-team

@prmerger-automator prmerger-automator bot added the aq-pr-triaged Tracking label for the PR review team label Nov 21, 2023
Copy link

@orcmid orcmid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree with this change. The current text is intended to make a contrast that it does very well. There are some additional contrasts that could be made, in particular,

  1. The inline modifier, not unlike the register modifier, is a suggestion and need not be honored by the compiler depending on technical determinations. There are also technical limitations.
  2. An inline procedure may remain available for reference by a pointer and that can be passed as a parameter. (This might cause an out-of-line version along with inline instances.)
  3. (perhaps) there can be some involvement of link-time code generation also.

But overall, I would leave the current text alone.

PS: In some sense, a pre-processor function-form definition has its usages mostly in-line, although there are other quirks (including how references to variables are resolved). And they are never external although shareable in headers. Appearing to point to/through (the expansion of) one is very quirky.

@FrankHB
Copy link

FrankHB commented Nov 21, 2023

I disagree with this change. The current text is intended to make a contrast that it does very well. There are some additional contrasts that could be made, in particular,

  1. The inline modifier, not unlike the register modifier, is a suggestion and need not be honored by the compiler depending on technical determinations. There are also technical limitations.
  2. An inline procedure may remain available for reference by a pointer and that can be passed as a parameter. (This might cause an out-of-line version along with inline instances.)
  3. (perhaps) there can be some involvement of link-time code generation also.

But overall, I would leave the current text alone.

PS: In some sense, a pre-processor function-form definition has its usages mostly in-line, although there are other quirks (including how references to variables are resolved). And they are never external although shareable in headers. Appearing to point to/through (the expansion of) one is very quirky.

Seems plausible, but the points are rather weak.

  1. Inline functions as replacements of function-like macros have nothing to do with whether inline is a suggestion or not.
  2. The ability of being used as a referent is from the fact it defines an well-typed entity which can be expressed as an lvalue, with nothing to do with inline.
  3. This is an implementation detail. And are you sure that LTCG will make a difference just because of inline?

However, the text should be preserved for following reasons:

  1. Function-like macros share syntaxes with function call expressions before the end of preprocessor phases. That is, the source code will look exactly the same between some typical use of macro expansions and function calls. Sometimes they are exchangable, but sometimes they are not. The caveats of side effects happen to be useful in this sense, and it is dangerous to abuse the assumption that an inline function is merely the replacement of a function-like macro.
  2. Historically, inline functions are invented to get rid of the drawbacks of certain function-like macros. This is more concerned in traditional C (due to the fact that lacking of the inline functions will make the function-like macros more usual than it needed to be), but it is still true even in modern C and C++.

The current text should be improved to address the points above explicitly in addition to the code example. Besides, the necessity of inline in such cases should be explained (i.e. otherwise there would be ODR violations; also better a note of constexpr). Otherwise, it is somewhat confusing.

NOTE: There are some substantially more serious PL-theoretical topics beyond the languages discussed here. This makes a closer of applicative functions to operative ones (generalized macros). In paticular, consider purely functional languages like pure lambda calculi, whose functions (the semantic objects introduced by syntactic forms named lambda abstrctions) can cover both kinds. In such cases, preprocessors, or even the function-like macros themselves, are implementation details which only show effect in some static phases (of limitations such as a macro must be expanded before some other evaluations of ordinary expressions including function calls). I'm not that interested to expand the topic more here; anyway, it should be a practice left to designers, not ordinary users, of languages.

@orcmid
Copy link

orcmid commented Nov 21, 2023

The inline keyword tells the compiler to substitute the code within the function definition for every instance of a function call.

That first line of the mentioned page is more objectionable. I would say the inline modifier is a suggestion that usage of a function be made as fast as possible, often leading to usages being expanded in place, avoiding the passing of parameters and return values when employing a single implementation.

With regard to contrasting with use of macros, the term macro is used throughout the ISO specifications for pre-processor defined expansions of all forms. (I am looking at ISO C11; I am certain that ISO C++ is the same in this respect.) So it is a term of art with respect to C/C++ preprocessing.

@FrankHB These pages are devoted to the use of VC/C++ on the Windows platform and are related to the Microsoft compiler support of C/C++. As an early adherent of functional programming, I am not confused on the matter and any PL discussion seems very off-topic.

@Mq-b
Copy link
Contributor Author

Mq-b commented Nov 22, 2023

I think we should pay more attention to the meaning of inline keyword in C++ language level itself, the document used to inline modified functions and macros compared, itself is a little strange, because first of all, the language level does not have this meaning, and secondly whether it is completely inline is not necessarily, the document to express unless the function must be inline and macro comparison. Then the example is not good enough.

Because the meaning of the keyword inline for functions came to mean "multiple definitions are permitted" rather than "inlining is preferred", that meaning was extended to variables. (since C++17)

This is probably more of a historical issue, but this page is in the C++ section, so I think we can simply delete this description.

We should even add more description for inline functions, like cppreference

@orcmid
Copy link

orcmid commented Nov 22, 2023

@Mq-b

Because the meaning of the keyword inline for functions came to mean "multiple definitions are permitted" rather than "inlining is preferred", that meaning was extended to variables. (since C++17)

I did check that at your suggestion. Thanks for that.

It is a little odd because (since C++17 evidently) any function defined in a translation unit can be in-lined although giving permission (per cppreference) is a bit strange. Of course there are various constraints and I suppose diagnostics when a translation unit violates a constraint. The conditions on multiple translation units must be interesting to check (or not).

I'm not certain that, at a general level, there is much difference between "suggesting" and "permitting." It would be interesting to know what the impact was and are for Microsoft implementations, although I tend to be more keen on portable interpretations.

@Mq-b Mq-b requested a review from orcmid November 22, 2023 07:15
@Mq-b
Copy link
Contributor Author

Mq-b commented Nov 22, 2023

I think we should go back to the original question. I think the description of this paragraph is not good and appropriate, and it can be deleted directly.

The discussion should be whether to remove, or modify, or add certain descriptions.

@orcmid
Copy link

orcmid commented Nov 22, 2023

@Mq-b

The discussion should be whether to remove, or modify, or add certain descriptions.

I thought that is what we have been doing. I have a follow-up observation about the cppreference explanation though. It strikes me that what it says about method implementations there is not always true, thinking of references to instances of virtual classes and, of course, interfaces. I suppose it matters when methods are used internally to the instance.

In any case, the use of "macro" with regard to the preprocessor-defined function forms is not objectionable. Is the objection to the examples and could they be done better? Is the objection to the statement that inline always causes in-lining?

@Mq-b
Copy link
Contributor Author

Mq-b commented Nov 23, 2023

In any case, the use of "macro" with regard to the preprocessor-defined function forms is not objectionable. Is the objection to the examples and could they be done better?

There is nothing wrong with this example.

Is the objection to the statement that inline always causes in-lining?

Yes.Neither the C++ standard, the C standard, gcc, clang, msvc, has ever said that its various inline methods, compiler extensions, are mandatory.

Going back to the original question, I admit that there is some truth to the msvc documentation and the contrast between macros and inline functions, but in general, I still think it's all historical.

And in the current example:

inline char toupper( char a );

The toupper function, I think more attention should also be paid to what 'inline' means at the language level.

And the contrast in the document is the default: 'inline' keyword modified functions must be inline.

However, I would like to delete the section 'Inline functions vs. macros'.

Although there is a certain degree of rationality, the two are still completely different things, and the similarities mainly lie in the non-linguistic level.

@orcmid
Copy link

orcmid commented Nov 23, 2023

@Mq-b

cppreference doesn't mention macros.

I hate to disappoint you. cppreference is not authoritative.

The use of the term "macro" for preprocessor-defined symbols and function forms has been standard language since Kernighan & Ritchie. I don't have my hands on Stroustrup but every ISO standard I have seen uses the term and all of the C++ books I just grabbed off my shelves use the term "macro" very consistently.

Also, there is use of the term "macro" at cppreference preprocessor.

I agree one does not need to know about the preprocessor introduction of in-line code in order to understand the inline modifier.

@Mq-b
Copy link
Contributor Author

Mq-b commented Nov 23, 2023

I agree one does not need to know about the preprocessor introduction of in-line code in order to understand the inline modifier.

So what are you going to do?

Copy link

@frederick-vs-ja frederick-vs-ja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should drop a valuable paragraph.

.gitignore Outdated
@@ -14,3 +14,4 @@ _themes.VS.Modern/
# Documentation build
/docs/vcppdocs
debug.log
/.vs

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be an unrelated change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have deleted

@@ -202,62 +202,6 @@ Assuming coordinate manipulation is a relatively common operation in a client of

- Return

## Inline functions vs. macros

Inline functions are similar to macros, because the function code is expanded at the point of the call at compile time. However, inline functions are parsed by the compiler, and macros are expanded by the preprocessor. As a result, there are several important differences:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep this paragraph.

It seems to me that only "Inline functions are similar to macros" needs to be improved. They are very different to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also include the fact that inline substitution is not mandatory, it occurs at the compiler's discretion, in the list. Currently the wording is confusing. Inline functions are similar to macros, because the function code is expanded at the point of the call at compile time. sounds like the substitution always happens.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codeworm96 Your idea is also my idea.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that only "Inline functions are similar to macros" needs to be improved.

I agree. The statement is not that rigorous, and this causal relationship is also kind of far-fetched.

Copy link
Contributor Author

@Mq-b Mq-b Nov 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frederick-vs-ja

Inline functions are similar to macros, because the function code is expanded at the point of the call at compile time.

I think we can just delete this paragraph and keep the last one:

inline functions are parsed by the compiler, and macros are expanded by the preprocessor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace this paragraph with:

Inline functions vs. macros

inline functions are parsed by the compiler, and macros are expanded by the preprocessor.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original wasn't good, and I'm not sure this is an improvement. 'Parsed by the compiler', although technically true, only indirectly conveys useful information. The crux of the matter that we are trying to get at is that the compiler, at its discretion, actually compiles the function and drops the code of the body into your code without the overhead of a function call, and with the benefit of actually going through the compiler so that language syntax and semantics are properly observed.
I see what the original author was trying to do here, but I think orienting the discussion about what an inline function is by comparing them with macros hurts more than it helps. I'll take a whack at redoing this section and we can see if it's an improvement.

@frederick-vs-ja
Copy link

frederick-vs-ja commented Nov 23, 2023

@orcmid I think this paragraph from @FrankHB's comments is related and helpful, which should help to explain why inline functions are considered similar to macros:

The current text should be improved to address the points above explicitly in addition to the code example. Besides, the necessity of inline in such cases should be explained (i.e. otherwise there would be ODR violations; also better a note of constexpr). Otherwise, it is somewhat confusing.

Copy link
Contributor

Learn Build status updates of commit 93025d3:

✅ Validation status: passed

File Status Preview URL Details
.gitignore ✅Succeeded
docs/cpp/inline-functions-cpp.md ✅Succeeded

For more details, please refer to the build report.

For any questions, please:

Copy link
Contributor

PRMerger Results

Issue Description
Unapproved file extension(s) This PR contains file types that are not supported in the repo. The only supported file types are jpg, gif, png, json, svg and md.
Repository root file This pull request contains a file submitted to the root of the repository.

Copy link
Contributor

Learn Build status updates of commit 994d366:

✅ Validation status: passed

File Status Preview URL Details
.gitignore ✅Succeeded
docs/cpp/inline-functions-cpp.md ✅Succeeded

For more details, please refer to the build report.

For any questions, please:

Copy link
Contributor

PRMerger Results

Issue Description
Unapproved file extension(s) This PR contains file types that are not supported in the repo. The only supported file types are jpg, gif, png, json, svg and md.
Repository root file This pull request contains a file submitted to the root of the repository.

Copy link
Collaborator

@TylerMSFT TylerMSFT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your comments and agree. I'll take a shot this week and we'll see if we can get it in a better place. I'll edit in this PR if alright with you.

.gitignore Outdated
@@ -13,4 +13,4 @@ _themes.VS.Modern/

# Documentation build
/docs/vcppdocs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this change about? Can you revert this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your reminding.
Didn't notice a blank line at the end, deleted.

@@ -202,62 +202,6 @@ Assuming coordinate manipulation is a relatively common operation in a client of

- Return

## Inline functions vs. macros

Inline functions are similar to macros, because the function code is expanded at the point of the call at compile time. However, inline functions are parsed by the compiler, and macros are expanded by the preprocessor. As a result, there are several important differences:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original wasn't good, and I'm not sure this is an improvement. 'Parsed by the compiler', although technically true, only indirectly conveys useful information. The crux of the matter that we are trying to get at is that the compiler, at its discretion, actually compiles the function and drops the code of the body into your code without the overhead of a function call, and with the benefit of actually going through the compiler so that language syntax and semantics are properly observed.
I see what the original author was trying to do here, but I think orienting the discussion about what an inline function is by comparing them with macros hurts more than it helps. I'll take a whack at redoing this section and we can see if it's an improvement.

Copy link
Contributor

Learn Build status updates of commit 1783fc0:

❌ Validation status: errors

Please follow instructions here which may help to resolve issue.

File Status Preview URL Details
❌Error Details

  • [Error: RuningBuildFailed] Some unexpected errors happened when running build, please open a ticket in https://aka.ms/SiteHelp and include the error report for our team to troubleshoot

For more details, please refer to the build report.

Note: Your PR may contain errors or warnings or suggestions unrelated to the files you changed. This happens when external dependencies like GitHub alias, Microsoft alias, cross repo links are updated. Please use these instructions to resolve them.

For any questions, please:

Take a shot at updating the macro/inline function comparison
Copy link
Contributor

Learn Build status updates of commit 4b2340d:

❌ Validation status: errors

Please follow instructions here which may help to resolve issue.

File Status Preview URL Details
❌Error Details

  • [Error: CannotMergeCommit] Cannot merge commit 4b2340da863b2ce8a354e417334b0dc1b1aa1dc4 in branch Inline-functions-vs-macros of repository https://github.com/Mq-b/cpp-docs_inline into branch main (commit ae7e3ca9fd078104df3ad60abcae8337275ff152). Please follow this documentation: https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/ to use git.exe to resolve you content conflicts locally and then push to remote.

For more details, please refer to the build report.

Note: Your PR may contain errors or warnings or suggestions unrelated to the files you changed. This happens when external dependencies like GitHub alias, Microsoft alias, cross repo links are updated. Please use these instructions to resolve them.

For any questions, please:

@TylerMSFT
Copy link
Collaborator

TylerMSFT commented Dec 8, 2023

@Mq-b, @orcmid, @frederick-vs-ja, @codeworm96, et. al: I made a quick update for the macro/inline function comparison section tonight, and a couple other places as I read through the article. Let me know what you think.
I'm not totally convinced that the macro vs inline function section is essential, but there may be some utility in pointing out a few differences.

Copy link
Contributor

Learn Build status updates of commit 9d3f5d3:

✅ Validation status: passed

File Status Preview URL Details
docs/cpp/inline-functions-cpp.md ✅Succeeded

For more details, please refer to the build report.

For any questions, please:

Copy link
Contributor

PRMerger Results

Issue Description
File Change Percent This PR contains file(s) with more than 30% file change.

Copy link

@orcmid orcmid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a lot of material. I think there are some confusing wordings. And in the example of

#define mult(a, b) a * b

In the explanation of why this is not the same as multiply(a, b), it is valuable to point out the more-careful
recommended practice,

#define mult(a, b) ((a) * (b))

I will review more closely in my morning afternoon.

@TylerMSFT
Copy link
Collaborator

Regarding the best practice, my goal isn't to divert into best practices for macros, but show how things can go awry between using a macro and a function.

@orcmid
Copy link

orcmid commented Dec 9, 2023

@TylerMSFT > Regarding the best practice, my goal isn't to divert into best practices for macros, but show how things can go awry between using a macro and a function.

OH. I thought showing that companion example would help folks understand how it is that cases like mult(a, b) get into trouble. Just for clarity of that particular one.

Some edits. Incorp ocrmid's feedback.
@TylerMSFT
Copy link
Collaborator

@orcmid, I incorporated a nod to your macro definition best practices suggestion.
Tomorrow I'll submit this PR.

Copy link
Contributor

Learn Build status updates of commit 14ca930:

✅ Validation status: passed

File Status Preview URL Details
docs/cpp/inline-functions-cpp.md ✅Succeeded

For more details, please refer to the build report.

For any questions, please:

Copy link
Contributor

PRMerger Results

Issue Description
File Change Percent This PR contains file(s) with more than 30% file change.

Copy link
Contributor

Learn Build status updates of commit f9fee1a:

✅ Validation status: passed

File Status Preview URL Details
docs/cpp/inline-functions-cpp.md ✅Succeeded

For more details, please refer to the build report.

For any questions, please:

Copy link
Contributor

PRMerger Results

Issue Description
File Change Percent This PR contains file(s) with more than 30% file change.

@TylerMSFT
Copy link
Collaborator

#sign-off

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants