F
fjansen
I'm trying to understand the underlying issue in my code that is
generating the following compile-time error message:
SingleLevelLogicalUnitNumber.cpp: In member function `bool
scsi::SingleLevelLogicalUnitNumber::invariant() const':
SingleLevelLogicalUnitNumber.cpp:37: error: invalid static_cast from
type `scsi::LogicalUnitAddressingField' to type `const
scsi:
eripheralDeviceAddress&'
The code section in question is the following:
bool SingleLevelLogicalUnitNumber::invariant() const {
bool level0Ok = false;
LogicalUnitAddressingField::Method addressMethod =
getAddress(0).getMethod();
if (LogicalUnitAddressingField:
eripheralDevice == addressMethod)
{
const PeripheralDeviceAddress & theAddress = static_cast<const
PeripheralDeviceAddress &>( getAddress(0) );
if (theAddress.getBusIdentifier() == 0 ) {
level0Ok = true;
}
} else if (LogicalUnitAddressingField::FlatSpace == addressMethod)
{
level0Ok = true;
} // else it's a violation of the class invariant to have any
other address method.
bool levels123Ok = MemIsZero( &myData[2], 6 );
return level0Ok && levels123Ok;
}
LogicalUnitAddressingField is a base class (non-virtual) for
PeripheralDeviceAddress (see class definitions below) and I would
expect that this cast would be legal; what am I missing here?
Thanks,
Frank
#ifndef SCSI_LOGICALUNITADDRESSINGFIELD_H
#define SCSI_LOGICALUNITADDRESSINGFIELD_H 1
#include "services/dbc.h"
#include <stdint.h>
#ifdef __GNUC__
#if __GNUCC < 3
#include <iostream>
#else
#include <ostream>
#endif
#else // there are other compilers, right?
#include <ostream>
#endif // __GNUC__
namespace scsi {
class LogicalUnitAddressingField {
public:
enum Method {
LogicalUnit = 2, // Logical unit addressing method
PeripheralDevice = 0, // Peripheral device addressing method
FlatSpace = 1, // Flat space addressing method
ExtendedLogicalUnit = 3 // Extended logical unit addressing
method
};
/**
* Construct a default logical unit addressing field.
*/
LogicalUnitAddressingField() {
myAddress[0] = '\0';
myAddress[1] = '\0';
}
/**
* Construct a logical unit addressing field.
*/
LogicalUnitAddressingField( Method itsAddressMethod, unsigned int
itsMethodSpecificAddress ) {
myAddress[0] = static_cast<uint8_t>( (itsAddressMethod << 6) |
((itsMethodSpecificAddress >> 8) & 0x3f) );
myAddress[1] = static_cast<uint8_t>( itsMethodSpecificAddress
& 0xff );
REQUIRE( itsMethodSpecificAddress <= 0x3fff );
}
/**
* Construct a logical unit addressing field from two bytes of
data.
*/
LogicalUnitAddressingField( const uint8_t * itsData ) {
myAddress[0] = itsData[0];
myAddress[1] = itsData[1];
}
/**
* Destroy a logical unit addressing field.
* @preconditions invariant()
*/
~LogicalUnitAddressingField() {}
#ifndef NDEBUG
/**
* Class invariant
*/
bool invariant() const;
#endif // NDEBUG
/**
* Return my addressing method.
*/
Method getMethod() const {
return static_cast<Method>( (myAddress[0] >> 6) & 0x03 );
}
/**
* Return my data.
*/
const uint8_t * getData() const {
return myAddress;
}
/**
* Print the address field on the supplied ostream.
*/
void printOn( std:
stream & os ) const;
protected:
/**
* My address.
*/
uint8_t myAddress[2];
};
} // namespace scsi
#endif // SCSI_LOGICALUNITADDRESSINGFIELD_H
#ifndef SCSI_PERIPHERALDEVICEADDRESS_H
#define SCSI_PERIPHERALDEVICEADDRESS_H 1
#include "LogicalUnitAddressingField.h"
#include "services/dbc.h"
namespace scsi {
class PeripheralDeviceAddress : public LogicalUnitAddressingField {
public:
/**
* Construct a default peripheral device address.
* The default addresses LUN 0.
*/
PeripheralDeviceAddress()
: LogicalUnitAddressingField( PeripheralDevice, 0 )
{}
/**
* Construct a peripheral device address.
*/
PeripheralDeviceAddress( unsigned int itsBusIdentifier, unsigned
int itsTargetOrLun )
: LogicalUnitAddressingField( PeripheralDevice,
(itsBusIdentifier << 8) | itsTargetOrLun )
{
REQUIRE( (itsBusIdentifier < 64) && (itsTargetOrLun < 256) );
}
/**
* Destroy a peripheral device address.
* @preconditions invariant()
*/
~PeripheralDeviceAddress() {}
#ifndef NDEBUG
/**
* Class invariant
*/
bool invariant() const;
#endif // NDEBUG
/**
* Return my bus identifier.
*/
unsigned int getBusIdentifer() const {
return myAddress[0] & 0x3f;
}
};
} // namespace scsi
#endif // SCSI_PERIPHERALDEVICEADDRESS_H
generating the following compile-time error message:
SingleLevelLogicalUnitNumber.cpp: In member function `bool
scsi::SingleLevelLogicalUnitNumber::invariant() const':
SingleLevelLogicalUnitNumber.cpp:37: error: invalid static_cast from
type `scsi::LogicalUnitAddressingField' to type `const
scsi:
The code section in question is the following:
bool SingleLevelLogicalUnitNumber::invariant() const {
bool level0Ok = false;
LogicalUnitAddressingField::Method addressMethod =
getAddress(0).getMethod();
if (LogicalUnitAddressingField:
{
const PeripheralDeviceAddress & theAddress = static_cast<const
PeripheralDeviceAddress &>( getAddress(0) );
if (theAddress.getBusIdentifier() == 0 ) {
level0Ok = true;
}
} else if (LogicalUnitAddressingField::FlatSpace == addressMethod)
{
level0Ok = true;
} // else it's a violation of the class invariant to have any
other address method.
bool levels123Ok = MemIsZero( &myData[2], 6 );
return level0Ok && levels123Ok;
}
LogicalUnitAddressingField is a base class (non-virtual) for
PeripheralDeviceAddress (see class definitions below) and I would
expect that this cast would be legal; what am I missing here?
Thanks,
Frank
#ifndef SCSI_LOGICALUNITADDRESSINGFIELD_H
#define SCSI_LOGICALUNITADDRESSINGFIELD_H 1
#include "services/dbc.h"
#include <stdint.h>
#ifdef __GNUC__
#if __GNUCC < 3
#include <iostream>
#else
#include <ostream>
#endif
#else // there are other compilers, right?
#include <ostream>
#endif // __GNUC__
namespace scsi {
class LogicalUnitAddressingField {
public:
enum Method {
LogicalUnit = 2, // Logical unit addressing method
PeripheralDevice = 0, // Peripheral device addressing method
FlatSpace = 1, // Flat space addressing method
ExtendedLogicalUnit = 3 // Extended logical unit addressing
method
};
/**
* Construct a default logical unit addressing field.
*/
LogicalUnitAddressingField() {
myAddress[0] = '\0';
myAddress[1] = '\0';
}
/**
* Construct a logical unit addressing field.
*/
LogicalUnitAddressingField( Method itsAddressMethod, unsigned int
itsMethodSpecificAddress ) {
myAddress[0] = static_cast<uint8_t>( (itsAddressMethod << 6) |
((itsMethodSpecificAddress >> 8) & 0x3f) );
myAddress[1] = static_cast<uint8_t>( itsMethodSpecificAddress
& 0xff );
REQUIRE( itsMethodSpecificAddress <= 0x3fff );
}
/**
* Construct a logical unit addressing field from two bytes of
data.
*/
LogicalUnitAddressingField( const uint8_t * itsData ) {
myAddress[0] = itsData[0];
myAddress[1] = itsData[1];
}
/**
* Destroy a logical unit addressing field.
* @preconditions invariant()
*/
~LogicalUnitAddressingField() {}
#ifndef NDEBUG
/**
* Class invariant
*/
bool invariant() const;
#endif // NDEBUG
/**
* Return my addressing method.
*/
Method getMethod() const {
return static_cast<Method>( (myAddress[0] >> 6) & 0x03 );
}
/**
* Return my data.
*/
const uint8_t * getData() const {
return myAddress;
}
/**
* Print the address field on the supplied ostream.
*/
void printOn( std:
protected:
/**
* My address.
*/
uint8_t myAddress[2];
};
} // namespace scsi
#endif // SCSI_LOGICALUNITADDRESSINGFIELD_H
#ifndef SCSI_PERIPHERALDEVICEADDRESS_H
#define SCSI_PERIPHERALDEVICEADDRESS_H 1
#include "LogicalUnitAddressingField.h"
#include "services/dbc.h"
namespace scsi {
class PeripheralDeviceAddress : public LogicalUnitAddressingField {
public:
/**
* Construct a default peripheral device address.
* The default addresses LUN 0.
*/
PeripheralDeviceAddress()
: LogicalUnitAddressingField( PeripheralDevice, 0 )
{}
/**
* Construct a peripheral device address.
*/
PeripheralDeviceAddress( unsigned int itsBusIdentifier, unsigned
int itsTargetOrLun )
: LogicalUnitAddressingField( PeripheralDevice,
(itsBusIdentifier << 8) | itsTargetOrLun )
{
REQUIRE( (itsBusIdentifier < 64) && (itsTargetOrLun < 256) );
}
/**
* Destroy a peripheral device address.
* @preconditions invariant()
*/
~PeripheralDeviceAddress() {}
#ifndef NDEBUG
/**
* Class invariant
*/
bool invariant() const;
#endif // NDEBUG
/**
* Return my bus identifier.
*/
unsigned int getBusIdentifer() const {
return myAddress[0] & 0x3f;
}
};
} // namespace scsi
#endif // SCSI_PERIPHERALDEVICEADDRESS_H