question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

(cpp) Template parameters trigger class header rule

See original GitHub issue

Describe the issue

When using the template <class T> syntax in C++, the class keyword misleads the parser into thinking it’s found a class header, and goes into class title mode, if there’s some { shortly afterwards. The relevant rule is

https://github.com/highlightjs/highlight.js/blob/5b87cc4d106059bee1c30f123e5a4053e0af9de4/src/languages/c-like.js#L227

Which language seems to have the issue?

cpp

Are you using highlight or highlightAuto?

highlight. When using highlightAuto, the code snippet is mis-categorised as angelscript and parsed differently still.

Sample Code to Reproduce

template <class T> // comment
auto foo(T x) { … }

highlight.js marks this up as

<keyword>template</keyword> &lt;<class><keyword>class</keyword> <title>T</title>&gt; // <title>comment</title>
<title>auto</title> <title>foo</title>(<title>T</title> <title>x</title>) {</class> … }

Expected behavior

When replacing class with typename (which is 100% equivalent in this context), it’s marked up (more) correctly:

<keyword>template</keyword> &lt;<keyword>typename</keyword> T&gt; <comment>// comment</comment>
<function><keyword>auto</keyword> <title>foo</title><params>(T x)</params> </function>{ … }

Additional context

Present in master. Some earlier version used highlighted this correctly (presumably before support for class headers was added). Fundamentally the issue is that template parameter declarations aren’t handled at all by the lexer (by contrast, template argument lists do have rudimentary handling; i.e. usage rather than declaration).

A fix would probably require a separate mode for template parameter declarations, which is a hairy topic. In fact, correctly disambiguating the meaning of >> (can be right-shift operator or a terminating nested template argument list) is context-sensitive, and undecidable for the lexer (!) because its meaning can depend on the type of names it is applied to: a<b<c>>d can either be parsed as a variable declaration of d where the type has a nested template argument (list if a is a type), or as an expression involving less-than comparison and bit shifts, if a is a variable: https://godbolt.org/z/rM18oc

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
joshgoebelcommented, Oct 1, 2020

would you be open to a PR that increases overall reliability of C++ rendering at the cost of no longer recognising class/function declarations, and thus won’t highlight them as titles (nor the parameter lists)

I don’t think so - and definitely not before ruling out ALL other choices. That does not sound like a great path forward to me. If someone just wants colored keywords there are other highlighting options available that are much simpler. We try to go further than that - and we successfully highlight TONS of valid C++ code, just you’ve found one case where we don’t work so well.


Right now it seems your original issue would be fixed by simply adding a special rule for:

template <class [identifier]>

If that would not resolve the issue, please expand your issue to provide additional examples.

0reactions
klmrcommented, Oct 1, 2020

I’m happy to take a stab at this once I find some time but I agree with you that this probably can’t be solved entirely. In fact, I suspect that we may have to give up something else: would you be open to a PR that increases overall reliability of C++ rendering at the cost of no longer recognising class/function declarations, and thus won’t highlight them as titles (nor the parameter lists)? That would make things drastically easier, since the language definition no longer needs to try to infer this context, and reverts to being a glorified tokeniser.

Personally I’d classify title/params highlighting as “nice to have”, and stuff like correctly recognising comments and keywords as essential. The current version of the C++ highlighter (almost certainly unintentionally!) seems to prioritise them the other way round.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Class template argument deduction (CTAD) (since C++17)
In order to instantiate a class template, every template argument must be known, but not every template argument has to be specified.
Read more >
Templates, C++ FAQ
Unlike template functions, template classes (instantiations of class templates) need to be explicit about the parameters over which they are instantiating:.
Read more >
Template Argument Deduction of Class Templates
A constructor can deduce its type parameters from its constructor arguments. Here is a first example. // templateArgumentDeduction.cpp #include ...
Read more >
Define template in header file and definition in a cpp file within ...
What are you really trying to do? typename is not a valid name for the template arguments, and in that code base inherits...
Read more >
4.1.1 Function Template Declaration
Template instantiation involves generating a concrete class or function (instance) for a particular combination of template arguments. For example, the compiler ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found