Need Syntax Help: Return Pointer to Struct from Class

I wish to return a pointer to a structure from a function within a class, but I can’t seem to find the right syntax/signature to get it to compile. I’ve searched these forums, and googled it, and the way I am typing it looks correct, and I’ve experimented with where to place the *'s and get compile errors no matter what.

I made a simple test project just to try and figure it out, which I have posted below. I have a class, which is mostly a wrapper for a structure. The structure is a private member of the class. I have a function gettmPtr() which is supposed to return a pointer to that private structure. Yes, I realize it would be much simpler to just make the structure public. Yes, I realize what I’m trying to do is a bit screwball and not exactly good programming practice. Please don’t preach at me about that, I’ve been programming in other languages for 30 years. My ‘real’ project is much bigger than the testbed posted below, with many classes, many structures, and many complex functions. My purpose for returning a pointer to the structure rather than making it public is to force a level of abstraction. Oh yes, and I know about the standard time.h library.

The line at issue is near the end of the DateWiz.cpp file.
StructReturnTest.ino

////////////////////////////////////////////////////////////////////////
// * * * * Structure Return Test * * * *
//  File: StructReturnTest.ino
// (u) uncopyright 2014 Dr. Wizard, except where noted.
///////////////////////////////////////////////////////

#include <stdint.h>
#include "DateWiz.h"

class date_d date1(22,6,1963);
struct tmd* tmP;
struct tmd tmC;

void setup() {
  Serial.begin(9600);
  tmP = date1.gettmPtr();
  tmC = date1.gettmCopy();
  date1.setMonth(8);
  Serial.println(tmP->tm_month);
  Serial.println(tmC.tm_month);

} // END setup()

void loop() {
} // END loop()

DateWiz.h

////////////////////////////////////////////////////////////////////////
// * * * * Structure Return Test * * * *
//  File: DateWiz.h
// (u) uncopyright 2014 Dr. Wizard, except where noted.
///////////////////////////////////////////////////////

#include <stdint.h>

#ifndef _DATEWIZ_H
#define _DATEWIZ_H

//    STRUCTURES     //
struct tmd {
  uint8_t  tm_mday;     // Day of the Month         1-31
  uint16_t tm_year;     // Years                1900-2100
  uint8_t  tm_month;    // Month number             1-12
};  

//    CLASSES       //
//    date_d Class     //
class date_d {
  public:
    // Constructors, Destructor
    date_d();
    date_d(uint8_t dayOfMonth, uint8_t month, uint16_t years);
    // Member GET functions
    uint8_t  getDayOfMonth();
    uint8_t  getMonth();
    uint16_t getYear();
    // Member SET functions
    void setDayOfMonth(uint8_t days);
    void setMonth(uint8_t months);
    void setYear(uint16_t years);
    // Other GET functions
    struct tmd gettmCopy();
    struct tmd* gettmPtr();

  private:
    struct tmd _tmd;
}; // END date_d class definition

#endif

DateWiz.cpp

////////////////////////////////////////////////////////////////////////
// * * * * Structure Return Test * * * *
//  File: DateWiz.cpp
// (u) uncopyright 2014 Dr. Wizard, except where noted.
///////////////////////////////////////////////////////

#include <stdint.h>
#include "DateWiz.h"

// date_d Constructors, Destructor //
date_d::date_d() {
  // Constructor with NO parameters Defaults to the Unix Epoch - Jan 1st, 1970
  _tmd.tm_mday        = 1;          // Day of the Month         1-31
  _tmd.tm_year        = 1970;         // Years since 1900         0-255
  _tmd.tm_month       = 1;          // Month number             1-12
} // END constructor date_d()

date_d::date_d(uint8_t days, uint8_t months, uint16_t years) {
  _tmd.tm_mday        = days;          // Day of the Month         1-31
  _tmd.tm_month       = months;     // Month number             1-12
  _tmd.tm_year        = years;          // Full year number         0-?  (such as 2014)
} // END constructor date_d(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t days, uint8_t months, uint16_t years)

// date_d Member GET functions //
uint8_t  date_d::getDayOfMonth() {
  return _tmd.tm_mday;
} // END getDayOfMonth

uint8_t  date_d::getMonth() {
  return _tmd.tm_month;
} // END getMonth

uint16_t date_d::getYear() {
  return _tmd.tm_year;
} // END getYear

// date_d Member SET functions //
void date_d::setDayOfMonth(uint8_t days) {
  _tmd.tm_mday = days;
} // END setDayOfMonth

void date_d::setMonth(uint8_t months) {
  _tmd.tm_month = months;
} // END setMonth

void date_d::setYear(uint16_t years) {
  _tmd.tm_year = years;
} // End setYear

// date_d Other GET functions //
struct tmd date_d::gettmCopy() {
  return _tmd;
} // END gettmCopy

struct tmd* date_d::gettmPtr() {
  return _tmd*; // error: expected primary-expression before ';' token
} // END gettmPtr

Thanks in advance for your help!

class date_d date1(22,6,1963);

That's a pretty skimpy definition of a class. That is NOT how to create an instance of a class.

The structure is a private member of the class. I have a function gettmPtr() which is supposed to return a pointer to that private structure.

  return _tmd*; // error: expected primary-expression before ';' token

Not surprising. Try
return &_tmd;

Even better would be to have a member that was actually a pointer, and make that pointer point to the data, and return that pointer.

But, best would be to NOT try to return a pointer to a struct. Have three methods that return the data. That way, you can ditch the struct altogether, and the functions will still work.

Of course, for some caller to be able to understand the struct, the struct definition shouldn't be hidden in the class.

Thank you very much, Paul!! Good Karma to you! (The real kind, too!) I coulda sworn I had already tried that. But that may have been while I was still fixing other errors.

Thanks for the other suggestions as well, but as I noted, the code I posted was just a stripped down test case, my 'real' project is much larger and far more complicated, and those are things I had already taken into consideration, and rejected for various reasons.

The issue you really have to be careful about, is the allocation of memory for the structure, and it's scope, visibility and lifetime.

I was a Sr. Software Engineer for many years, I am now disabled/retired. I KNOW what I'm doing is a kludge, and not that great of a design. If this was a collaborative project with a bunch of Jr. developers working on it, I would never allow it! But this is my own personal hobby project and no-one will see the code except me. I will probably come up with a more elegant solution later, but for now, it gets me where I want to be. Scope and lifetime have already been taken into consideration. Thank you though!