Other Parts Discussed in Thread: SYSBIOS
Tool/software: TI C/C++ Compiler
I believe there is an error in the compiler as it appears to be incorrectly attempting to compile a non-array version of a template when it should have compiled the array version.
The following code is generating this error:
subdir_rules.mk:23: recipe for target 'main.obj' failed
"../main.cpp", line 159: error #138: expression must be a modifiable lvalue
Here is the code:
/*
* ======== main.c ========
*/
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <typeinfo>
/*
* ======== taskFxn ========
*/
Void taskFxn(UArg a0, UArg a1)
{
System_printf("enter taskFxn()\n");
Task_sleep(10);
System_printf("exit taskFxn()\n");
}
typedef unsigned int uint32;
typedef unsigned short uint16;
namespace Internal
{
class Eraser
{
public:
template <typename T>
Eraser(const T& t)
: mpData(new Impl<T>(t))
{
}
template <typename T, std::size_t I>
Eraser(const T (&t)[I])
: mpData(new ArrayImpl<T>(t, I))
{
}
~Eraser()
{
delete mpData;
}
void* GetData()
{
return mpData->GetData();
}
private:
struct Interface
{
virtual ~Interface()
{
}
virtual void* GetData() = 0;
};
template <typename T>
class Impl : public Interface
{
public:
Impl(const T& t)
: mpData(new T(t))
{
}
virtual ~Impl()
{
delete mpData;
}
virtual void* GetData()
{
return mpData;
}
private:
T* mpData;
};
template <typename T>
class ArrayImpl : public Interface
{
public:
ArrayImpl(const T* t, std::size_t count)
: mpData(new T[count])
{
for(std::size_t i = 0; i < count; ++i)
{
mpData[i] = t[i];
}
}
virtual ~ArrayImpl()
{
delete[] mpData;
}
virtual void* GetData()
{
return mpData;
}
private:
T* mpData;
};
mutable Interface* mpData;
};
}
class ElementInfo
{
public:
ElementInfo()
: mpDataType(0)
, mpData(0)
{
}
const std::type_info& GetDataType()
{
return *mpDataType;
}
Internal::Eraser* GetData()
{
return mpData;
}
private:
const std::type_info* mpDataType;
Internal::Eraser* mpData;
};
int mCurrentSize = 10;
ElementInfo* mpElements;
// Set, template non-array version
template <typename T>
void Set(uint32 dataId, const T& data)
{
if (dataId < mCurrentSize)
{
// In CCS, This line results in error: "../main.cpp", line 165: error #138: expression must be a modifiable lvalue
*reinterpret_cast<T*>(mpElements[dataId].GetData()->GetData()) = data;
}
}
// Set, template array version.
template <typename T, std::size_t I>
void Set(uint32 dataId, const T(&data)[I])
{
if (dataId < mCurrentSize)
{
for (uint32 i = 0; i < I; ++i)
{
reinterpret_cast<T*>(mpElements[dataId].GetData()->GetData())[i] = data[i];
}
}
}
Void RunTestCode()
{
int maxNumberOfElements = mCurrentSize;
mpElements = new ElementInfo[maxNumberOfElements];
uint32 dataId0 = 1;
uint16 dataValue = 100;
Set(dataId0, dataValue);
const uint32 arraySize = 3;
//const uint16 dataArray[arraySize] = { 0, 0, 0 }; // Using this line instead of the next line fixes a problem in the compiler.
uint16 dataArray[arraySize] = { 0, 0, 0 };
// Retrieving the first element using the wrong data type should fail.
Set(dataId0, dataArray);
}
/*
* ======== main ========
*/
Int main()
{
RunTestCode();
/*
Task_Handle task;
Error_Block eb;
System_printf("enter main()\n");
Error_init(&eb);
task = Task_create(taskFxn, NULL, &eb);
if (task == NULL) {
System_printf("Task_create() failed!\n");
BIOS_exit(0);
}
*/
//BIOS_start(); /* does not return */
return(0);
}