Navigation Menu

Skip to content
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

Compilation error using "template <class T>" (prototypes generated incorrectly) [imported] #472

Closed
cmaglie opened this issue Nov 15, 2012 · 16 comments
Labels
Component: Preprocessor The Arduino sketch preprocessor converts .ino files into C++ code before compilation Type: Bug
Milestone

Comments

@cmaglie
Copy link
Member

cmaglie commented Nov 15, 2012

This is Issue 472 moved from a Google Code project.
Added by 2011-02-06T15:31:57.000Z by leomi...@gmail.com.
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium, Component-IDE, Component-PreProcessor

Original description

I found an error using the last revision of Arduino IDE (0022).
This code doesn't compile correctly:

template <class T> int SRAM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
      EEPROM.write(ee++, *p++);
    return i;
}


template <class T> int SRAM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
      *p++ = EEPROM.read(ee++);
    return i;
}

The IDE returns this error:
error: expected ',' or '...' before '&' token
error: ISO C++ forbids declaration of 'T' with no type
error: 'T' has not been declared

Using version 0021 it works fine.

@nickgammon
Copy link

Can we promote this? Under version 1.5.8 of the IDE:

// generic minimum
template <typename T> T minimum (T a, T b) 
  {
  if (a < b)
    return a;
  return b;
  }  // end of minimum

void setup () 
  { 
  int foo = minimum (6, 7);
  }
void loop () { }

Gives error message:

sketch_oct08b.ino:3:1: error: 'T' does not name a type
Error compiling.

The code generated by the IDE and sent to the compiler is:

#line 1 "sketch_oct08b.ino"

#include "Arduino.h"
T minimum (T a, T b);
void setup ();
void loop ();
#line 2
template <typename T> T minimum (T a, T b)
  {
  if (a < b)
    return a;
  return b;
  }

void setup ()
  {
  int foo = minimum (6, 7);
  }
void loop () { }

Clearly the function-prototype generation is not recognizing this part:

template <typename T>

... as being part of a function declaration. Surely that is easy to fix?

@matthijskooijman
Copy link
Collaborator

Seems this would need to be fixed in these regexes:

https://github.com/arduino/Arduino/blob/master/app/src/processing/app/preproc/PdePreprocessor.java#L320-L321

Not sure if we'll actually make things better here. We should really make this preprocessing stuff deprecated...

@matthijskooijman matthijskooijman added Component: Preprocessor The Arduino sketch preprocessor converts .ino files into C++ code before compilation Type: Bug labels Oct 8, 2014
@nickgammon
Copy link

I don't particularly mind that (except it would take a while to take effect). The preprocessing stuff would be OK, if it worked consistently, but it doesn't. And then you have to have function prototypes sometimes which confuses people as to why you sometimes need them and sometimes not.

Here's another example, which doesn't use templates:

typedef void (*GeneralMessageFunction) ();

//void checkPin (const int pin, GeneralMessageFunction response); // prototype
void checkPin (const int pin, GeneralMessageFunction response)
  {
  }  // end of checkPin

void setup () { }
void loop () { }

With the function prototype commented out you get the error:

sketch_oct09a.ino:2:31: error: 'GeneralMessageFunction' has not been declared

The other side-effect is that often (in these cases) the wrong line gets highlighted by the IDE because the "real" problem is in the hidden prototype line which has been generated, and which the user doesn't see.

It's not that hard to teach people to use prototypes, and indeed if you follow a simple rule they aren't usually necessary:

Declare functions before you call them.

So, if you put setup() and loop() last, and the things they call ahead of them (earlier in the source), everything works without prototypes anyway.

@ffissore
Copy link
Contributor

Please checkout this thread [1] on devs mailing list and try one of the linked IDEs. It should fix almost all the problems reported in this issue. Typedefs are still incorrectly handled so @nickgammon example still won't work
[1] https://groups.google.com/a/arduino.cc/forum/#!topic/developers/4X2T3rCxXWM

@ffissore
Copy link
Contributor

With this latest build https://groups.google.com/a/arduino.cc/d/msg/developers/4X2T3rCxXWM/WbQ2_dGzuhsJ even typedefs will work fine

@ffissore ffissore modified the milestone: Release 1.6.5 Jun 5, 2015
@ffissore
Copy link
Contributor

Fixed by #3779

@ffissore ffissore added this to the Release 1.6.6 milestone Sep 11, 2015
tbowmo pushed a commit to tbowmo/Arduino that referenced this issue Jul 14, 2016
Fix sending buffer in MySigning.cpp
@danlsk
Copy link

danlsk commented Nov 28, 2016

I am using 1.6.8. I got this error: 'T' does not name a type. I don't see it fixed yet. Let me know if other version fixes this.

@Chris--A
Copy link
Contributor

@danlsk
You'll have to provide the code you are using (a small complete example). Gammon's code does not cause errors in 1.6.12/13.

Compiles fine:

// generic minimum
template <typename T> T minimum (T a, T b) 
  {
  if (a < b)
    return a;
  return b;
  }  // end of minimum

void setup () 
  { 
  int foo = minimum (6, 7);
  }
void loop () { }

@danlsk
Copy link

danlsk commented Nov 28, 2016

template <class T>
T sum (T a, T b){
  T result;
  result = a + b;
  return result;
}


void setup() {
  Serial.begin(9600);
  int i=5, j=6, k;
  double f=2.0, g=0.5, h;
  
  k = sum<int>(i,j);
  h = sum<double>(f,g);  
  
  Serial.println (k);
  Serial.println (h);
  
}

void loop() {
}

@danlsk
Copy link

danlsk commented Nov 28, 2016

Alright, I just figured out that it cannot break into 2 lines and must be on a single line.
template <class T> T sum (T a, T b)
instead of

template <class T>
  T sum (T a, T b)

But this one below works in 2 lines:

 template <class T>
 class mypair {
    T a,b;
  public:
    mypair (T first, T second)
      {a=first;b=second;}
    T getmax();
};

template <class T>
T mypair<T>::getmax(){
  T retval;
  retval = a>b? a : b;
  return retval;
}

void setup() {
  Serial.begin(9600);
  mypair <int> myobject (100,75);
  Serial.println(myobject.getmax());
}

void loop() {}

@Chris--A
Copy link
Contributor

Yeah, the class function works on multiple lines as the IDE does not generate a prototype for it. Only file scoped functions are generated.

IMO the multi line error should be fixed as templates can become very involved and a single line detracts from readability dramatically. Especially now that C++11 has been enabled, templates are a staple diet of the language and are more prevalent that ever (standard template lib for one).

At least there is a workaround for now.

@facchinm
Copy link
Member

This arduino/arduino-builder#182 PR should solve the multiline problem once for all , but the code is horribly convoluted and needs a big cleanup before merging. Anyway, if you could test it and report any bug you may encounter, it would be great!

@Chris--A
Copy link
Contributor

Will do, I can spend a little time trying to break it for you :)

@facchinm
Copy link
Member

@Chris--A ,
I rebased and refactored the code, it should be much better now 😄
@ArduinoBot should produce a build really soon so I'd really like you (and anyone interested) to test it!

@Chris--A
Copy link
Contributor

just got home from work, will give it a spin shortly.

@Chris--A
Copy link
Contributor

Chris--A commented Dec 1, 2016

Unfortunately there was no luck with the new code, test results here: arduino/arduino-builder#182 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Preprocessor The Arduino sketch preprocessor converts .ino files into C++ code before compilation Type: Bug
Projects
None yet
Development

No branches or pull requests

7 participants