Skip to content

fix ODR violation from redefining a struct via using declaration

Eli Schwartz requested to merge eli-schwartz/kfloppy:odr-violation into master

The issue is that

using varname = typename <definition>

instead of

typename varname <definition>

is really just "typedef but C++ish because it uses a C++ spelling" and a typedef isn't really appropriate here. Anyways, the result is that each time the header is include, a different (anonymous) struct is created, and then typedef'ed to a common name which unfortunately does nothing to make the struct match up.

Detected by compiling with GCC and -flto:

/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3_build/kfloppy_autogen/EWIEGA46WW/../../../kfloppy-23.04.3/format.h:176:7: error: type ‘struct FloppyAction’ violates the C++ One Definition Rule [-Werror=odr]
  176 | class FloppyAction : public KFAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:176:7: note: a different type is defined in another translation unit
  176 | class FloppyAction : public KFAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3_build/kfloppy_autogen/EWIEGA46WW/../../../kfloppy-23.04.3/format.h:214:19: note: the first difference of corresponding definitions is field ‘deviceInfo’
  214 |     const fdinfo *deviceInfo; ///< Configuration info (Pointer into list of "/dev/..." entries)
      |                   ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:214:19: note: a field of same name but different type is defined in another translation unit
  214 |     const fdinfo *deviceInfo; ///< Configuration info (Pointer into list of "/dev/..." entries)
      |                   ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3_build/kfloppy_autogen/EWIEGA46WW/../../../kfloppy-23.04.3/format.h:176:7: note: type ‘const struct fdinfo’ defined in anonymous namespace cannot match across the translation unit boundary
  176 | class FloppyAction : public KFAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:403:7: error: type ‘struct MinixFilesystem’ violates the C++ One Definition Rule [-Werror=odr]
  403 | class MinixFilesystem : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:403:7: note: a type with different bases is defined in another translation unit
  403 | class MinixFilesystem : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:353:7: error: type ‘struct Ext2Filesystem’ violates the C++ One Definition Rule [-Werror=odr]
  353 | class Ext2Filesystem : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:353:7: note: a type with different bases is defined in another translation unit
  353 | class Ext2Filesystem : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:323:7: error: type ‘struct FATFilesystem’ violates the C++ One Definition Rule [-Werror=odr]
  323 | class FATFilesystem : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:323:7: note: a type with different bases is defined in another translation unit
  323 | class FATFilesystem : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:258:7: error: type ‘struct FDFormat’ violates the C++ One Definition Rule [-Werror=odr]
  258 | class FDFormat : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:258:7: note: a type with different bases is defined in another translation unit
  258 | class FDFormat : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:293:7: error: type ‘struct DDZeroOut’ violates the C++ One Definition Rule [-Werror=odr]
  293 | class DDZeroOut : public FloppyAction
      |       ^
/var/tmp/portage/kde-apps/kfloppy-23.04.3/work/kfloppy-23.04.3/format.h:293:7: note: a type with different bases is defined in another translation unit
  293 | class DDZeroOut : public FloppyAction
      |       ^
lto1: some warnings being treated as errors

Merge request reports