From 982b4ced7d65202dfd9639c06048d13bc26e949c Mon Sep 17 00:00:00 2001 From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Mon, 1 Jul 2019 20:54:14 +0000 Subject: [PATCH] Replace all ASSERT_*() macros with STATIC_ASSERT(). static_assert.h: New file with STATIC_ASSERT() macro using C++11 static_assert() if available. Makefile.am, os_win32/vc14/smart*.vcxproj*: Add new file. git-svn-id: https://svn.code.sf.net/p/smartmontools/code/trunk@4934 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- smartmontools/ChangeLog | 5 ++ smartmontools/Makefile.am | 2 + smartmontools/atacmdnames.cpp | 11 +-- smartmontools/atacmds.h | 65 ++++++-------- smartmontools/dev_intelliprop.cpp | 6 +- smartmontools/nvmecmds.cpp | 13 +-- smartmontools/nvmecmds.h | 12 ++- smartmontools/os_win32.cpp | 89 ++++++++----------- smartmontools/os_win32/vc14/smartctl.vcxproj | 1 + .../os_win32/vc14/smartctl.vcxproj.filters | 1 + smartmontools/os_win32/vc14/smartd.vcxproj | 1 + .../os_win32/vc14/smartd.vcxproj.filters | 1 + smartmontools/static_assert.h | 27 ++++++ 13 files changed, 126 insertions(+), 108 deletions(-) create mode 100644 smartmontools/static_assert.h diff --git a/smartmontools/ChangeLog b/smartmontools/ChangeLog index cd432f29d..53351d2c0 100644 --- a/smartmontools/ChangeLog +++ b/smartmontools/ChangeLog @@ -2,6 +2,11 @@ $Id$ 2019-07-01 Christian Franke <franke@computer.org> + Replace all ASSERT_*() macros with STATIC_ASSERT(). + static_assert.h: New file with STATIC_ASSERT() macro using C++11 + static_assert() if available. + Makefile.am, os_win32/vc14/smart*.vcxproj*: Add new file. + os_win32/vc14/smart*.vcxproj*: Add missing scsinvme.cpp. 2019-06-28 Christian Franke <franke@computer.org> diff --git a/smartmontools/Makefile.am b/smartmontools/Makefile.am index 40051aed7..1cfdff796 100644 --- a/smartmontools/Makefile.am +++ b/smartmontools/Makefile.am @@ -83,6 +83,7 @@ smartctl_SOURCES = \ scsinvme.cpp \ scsiprint.cpp \ scsiprint.h \ + static_assert.h \ utility.cpp \ utility.h \ sg_unaligned.h @@ -154,6 +155,7 @@ smartd_SOURCES = \ scsicmds.h \ scsiata.cpp \ scsinvme.cpp \ + static_assert.h \ utility.cpp \ utility.h \ sg_unaligned.h diff --git a/smartmontools/atacmdnames.cpp b/smartmontools/atacmdnames.cpp index 073fb22f1..3fe5b847a 100644 --- a/smartmontools/atacmdnames.cpp +++ b/smartmontools/atacmdnames.cpp @@ -1,15 +1,17 @@ /* * atacmdnames.cpp * - * Home page of code is: http://www.smartmontools.org + * Home page of code is: https://www.smartmontools.org * - * Copyright (C) 2003-8 Philip Williams - * Copyright (C) 2012 Christian Franke + * Copyright (C) 2003-08 Philip Williams + * Copyright (C) 2012-19 Christian Franke * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "atacmdnames.h" +#include "static_assert.h" + #include <stdlib.h> #include <stdio.h> @@ -301,8 +303,7 @@ const char * const command_table[] = { cmd_vendor_specific }; -typedef char ASSERT_command_table_size[ - sizeof(command_table)/sizeof(command_table[0]) == 256 ? 1 : -1]; +STATIC_ASSERT(sizeof(command_table) == 256 * sizeof(command_table[0])); /* Returns the name of the command (and possibly sub-command) with the given command code and feature register values. For most command codes this diff --git a/smartmontools/atacmds.h b/smartmontools/atacmds.h index 71e37b285..94c9ae9ba 100644 --- a/smartmontools/atacmds.h +++ b/smartmontools/atacmds.h @@ -1,10 +1,10 @@ /* * atacmds.h * - * Home page of code is: http://www.smartmontools.org + * Home page of code is: https://www.smartmontools.org * * Copyright (C) 2002-11 Bruce Allen - * Copyright (C) 2008-17 Christian Franke + * Copyright (C) 2008-19 Christian Franke * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * * SPDX-License-Identifier: GPL-2.0-or-later @@ -16,14 +16,7 @@ #define ATACMDS_H_CVSID "$Id$" #include "dev_interface.h" // ata_device - -// Macro to check expected size of struct at compile time using a -// dummy typedef. On size mismatch, compiler reports a negative array -// size. If you see an error message of this form, it means that the -// #pragma pack(1) pragma below is not having the desired effect on -// your compiler. -#define ASSERT_SIZEOF_STRUCT(s, n) \ - typedef char assert_sizeof_struct_##s[(sizeof(struct s) == (n)) ? 1 : -1] +#include "static_assert.h" // Add __attribute__((packed)) if compiler supports it // because some gcc versions (at least ARM) lack support of #pragma pack() @@ -137,7 +130,7 @@ struct ata_identify_device { unsigned short words088_255[168]; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_identify_device, 512); +STATIC_ASSERT(sizeof(ata_identify_device) == 512); /* ata_smart_attribute is the vendor specific in SFF-8035 spec */ #pragma pack(1) @@ -152,7 +145,7 @@ struct ata_smart_attribute { unsigned char reserv; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_attribute, 12); +STATIC_ASSERT(sizeof(ata_smart_attribute) == 12); // MACROS to interpret the flags bits in the previous structure. // These have not been implemented using bitflags and a union, to make @@ -222,7 +215,7 @@ struct ata_smart_values { unsigned char chksum; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_values, 512); +STATIC_ASSERT(sizeof(ata_smart_values) == 512); /* Maxtor, IBM: self-test failure checkpoint byte meaning: 00 - write test @@ -241,7 +234,7 @@ struct ata_smart_threshold_entry { unsigned char reserved[10]; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_threshold_entry, 12); +STATIC_ASSERT(sizeof(ata_smart_threshold_entry) == 12); /* Format of Read SMART THreshold Command */ /* Compare to ata_smart_values above */ @@ -253,7 +246,7 @@ struct ata_smart_thresholds_pvt { unsigned char chksum; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_thresholds_pvt, 512); +STATIC_ASSERT(sizeof(ata_smart_thresholds_pvt) == 512); // Table 42 of T13/1321D Rev 1 spec (Error Data Structure) @@ -272,7 +265,7 @@ struct ata_smart_errorlog_error_struct { unsigned short timestamp; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_error_struct, 30); +STATIC_ASSERT(sizeof(ata_smart_errorlog_error_struct) == 30); // Table 41 of T13/1321D Rev 1 spec (Command Data Structure) @@ -289,7 +282,7 @@ struct ata_smart_errorlog_command_struct { unsigned int timestamp; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_command_struct, 12); +STATIC_ASSERT(sizeof(ata_smart_errorlog_command_struct) == 12); // Table 40 of T13/1321D Rev 1 spec (Error log data structure) #pragma pack(1) @@ -298,7 +291,7 @@ struct ata_smart_errorlog_struct { struct ata_smart_errorlog_error_struct error_struct; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_struct, 90); +STATIC_ASSERT(sizeof(ata_smart_errorlog_struct) == 90); // Table 39 of T13/1321D Rev 1 spec (SMART error log sector) #pragma pack(1) @@ -311,7 +304,7 @@ struct ata_smart_errorlog { unsigned char checksum; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_errorlog, 512); +STATIC_ASSERT(sizeof(ata_smart_errorlog) == 512); // Extended Comprehensive SMART Error Log data structures @@ -342,7 +335,7 @@ struct ata_smart_exterrlog_command unsigned int timestamp; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_command, 18); +STATIC_ASSERT(sizeof(ata_smart_exterrlog_command) == 18); // Error data structure // Table A.10 T13/1699-D Revision 6a @@ -367,7 +360,7 @@ struct ata_smart_exterrlog_error unsigned short timestamp; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_error, 34); +STATIC_ASSERT(sizeof(ata_smart_exterrlog_error) == 34); // Error log data structure // Table A.8 of T13/1699-D Revision 6a @@ -378,7 +371,7 @@ struct ata_smart_exterrlog_error_log ata_smart_exterrlog_error error; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_error_log, 124); +STATIC_ASSERT(sizeof(ata_smart_exterrlog_error_log) == 124); // Ext. Comprehensive SMART error log // Table A.7 of T13/1699-D Revision 6a @@ -394,7 +387,7 @@ struct ata_smart_exterrlog unsigned char checksum; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog, 512); +STATIC_ASSERT(sizeof(ata_smart_exterrlog) == 512); // Table 45 of T13/1321D Rev 1 spec (Self-test log descriptor entry) @@ -408,7 +401,7 @@ struct ata_smart_selftestlog_struct { unsigned char vendorspecific[15]; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_selftestlog_struct, 24); +STATIC_ASSERT(sizeof(ata_smart_selftestlog_struct) == 24); // Table 44 of T13/1321D Rev 1 spec (Self-test log data structure) #pragma pack(1) @@ -421,7 +414,7 @@ struct ata_smart_selftestlog { unsigned char chksum; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_selftestlog, 512); +STATIC_ASSERT(sizeof(ata_smart_selftestlog) == 512); // Extended SMART Self-test log data structures // See Section A.8 of @@ -441,7 +434,7 @@ struct ata_smart_extselftestlog_desc unsigned char vendorspecific[15]; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_extselftestlog_desc, 26); +STATIC_ASSERT(sizeof(ata_smart_extselftestlog_desc) == 26); // Extended Self-test log data structure // Table A.12 of T13/1699-D Revision 6a @@ -457,7 +450,7 @@ struct ata_smart_extselftestlog unsigned char chksum; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_extselftestlog, 512); +STATIC_ASSERT(sizeof(ata_smart_extselftestlog) == 512); // SMART LOG DIRECTORY Table 52 of T13/1532D Vol 1 Rev 1a #pragma pack(1) @@ -466,7 +459,7 @@ struct ata_smart_log_entry { unsigned char reserved; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_log_entry, 2); +STATIC_ASSERT(sizeof(ata_smart_log_entry) == 2); #pragma pack(1) struct ata_smart_log_directory { @@ -474,7 +467,7 @@ struct ata_smart_log_directory { struct ata_smart_log_entry entry[255]; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_smart_log_directory, 512); +STATIC_ASSERT(sizeof(ata_smart_log_directory) == 512); // SMART SELECTIVE SELF-TEST LOG Table 61 of T13/1532D Volume 1 // Revision 3 @@ -484,7 +477,7 @@ struct test_span { uint64_t end; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(test_span, 16); +STATIC_ASSERT(sizeof(test_span) == 16); #pragma pack(1) struct ata_selective_self_test_log { @@ -501,7 +494,7 @@ struct ata_selective_self_test_log { unsigned char checksum; } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_selective_self_test_log, 512); +STATIC_ASSERT(sizeof(ata_selective_self_test_log) == 512); #define SELECTIVE_FLAG_DOSCAN (0x0002) #define SELECTIVE_FLAG_PENDING (0x0008) @@ -544,7 +537,7 @@ struct ata_sct_status_response unsigned char vendor_specific[32];// 480-511: vendor specific } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_sct_status_response, 512); +STATIC_ASSERT(sizeof(ata_sct_status_response) == 512); // SCT Error Recovery Control command (send with SMART_WRITE_LOG page 0xe0) // Table 88 of T13/1699-D Revision 6a @@ -558,7 +551,7 @@ struct ata_sct_error_recovery_control_command unsigned short words004_255[252]; // reserved } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_sct_error_recovery_control_command, 512); +STATIC_ASSERT(sizeof(ata_sct_error_recovery_control_command) == 512); // SCT Feature Control command (send with SMART_WRITE_LOG page 0xe0) // Table 72 of T13/1699-D Revision 3f @@ -573,7 +566,7 @@ struct ata_sct_feature_control_command unsigned short words005_255[251]; // reserved } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_sct_feature_control_command, 512); +STATIC_ASSERT(sizeof(ata_sct_feature_control_command) == 512); // SCT Data Table command (send with SMART_WRITE_LOG page 0xe0) // Table 73 of T13/1699-D Revision 3f @@ -586,7 +579,7 @@ struct ata_sct_data_table_command unsigned short words003_255[253]; // reserved } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_sct_data_table_command, 512); +STATIC_ASSERT(sizeof(ata_sct_data_table_command) == 512); // SCT Temperature History Table (read with SMART_READ_LOG page 0xe1) // Table 75 of T13/1699-D Revision 3f @@ -606,7 +599,7 @@ struct ata_sct_temperature_history_table signed char cb[478]; // 34-(34+cb_size-1): Circular buffer of temperature values } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(ata_sct_temperature_history_table, 512); +STATIC_ASSERT(sizeof(ata_sct_temperature_history_table) == 512); // Possible values for span_args.mode enum { diff --git a/smartmontools/dev_intelliprop.cpp b/smartmontools/dev_intelliprop.cpp index 02738a7f0..c67cf615a 100644 --- a/smartmontools/dev_intelliprop.cpp +++ b/smartmontools/dev_intelliprop.cpp @@ -1,7 +1,7 @@ /* * dev_intelliprop.cpp * - * Home page of code is: http://www.smartmontools.org + * Home page of code is: https://www.smartmontools.org * * Copyright (C) 2016 Casey Biemiller <cbiemiller@intelliprop.com> * @@ -10,7 +10,7 @@ #include "config.h" -#include "atacmds.h" //ATTR_PACKED and ASSERT_SIZEOF_STRUCT +#include "atacmds.h" // ATTR_PACKED, STATIC_ASSERT, ata_debugmode #include "dev_interface.h" #include "dev_intelliprop.h" #include "dev_tunnelled.h" @@ -71,7 +71,7 @@ struct iprop_internal_log uint16_t crc; // Bytes - [511:510] of Log C0 } ATTR_PACKED; #pragma pack() -ASSERT_SIZEOF_STRUCT(iprop_internal_log, 512); +STATIC_ASSERT(sizeof(iprop_internal_log) == 512); /** * buffer is a pointer to a buffer of bytes, which should include data and diff --git a/smartmontools/nvmecmds.cpp b/smartmontools/nvmecmds.cpp index 577422579..f5be9ab41 100644 --- a/smartmontools/nvmecmds.cpp +++ b/smartmontools/nvmecmds.cpp @@ -1,9 +1,9 @@ /* * nvmecmds.cpp * - * Home page of code is: http://www.smartmontools.org + * Home page of code is: https://www.smartmontools.org * - * Copyright (C) 2016 Christian Franke + * Copyright (C) 2016-19 Christian Franke * * SPDX-License-Identifier: GPL-2.0-or-later */ @@ -15,19 +15,12 @@ const char * nvmecmds_cvsid = "$Id$" NVMECMDS_H_CVSID; #include "dev_interface.h" -#include "atacmds.h" // swapx(), ASSERT_*(), dont_print_serial_number +#include "atacmds.h" // swapx(), dont_print_serial_number #include "scsicmds.h" // dStrHex() #include "utility.h" using namespace smartmontools; -// Check nvme_* struct sizes -ASSERT_SIZEOF_STRUCT(nvme_id_ctrl, 4096); -ASSERT_SIZEOF_STRUCT(nvme_id_ns, 4096); -ASSERT_SIZEOF_STRUCT(nvme_error_log_page, 64); -ASSERT_SIZEOF_STRUCT(nvme_smart_log, 512); - - // Print NVMe debug messages? unsigned char nvme_debugmode = 0; diff --git a/smartmontools/nvmecmds.h b/smartmontools/nvmecmds.h index e9cd38fce..d478914ab 100644 --- a/smartmontools/nvmecmds.h +++ b/smartmontools/nvmecmds.h @@ -1,9 +1,9 @@ /* * nvmecmds.h * - * Home page of code is: http://www.smartmontools.org + * Home page of code is: https://www.smartmontools.org * - * Copyright (C) 2016-18 Christian Franke + * Copyright (C) 2016-19 Christian Franke * * Original code from <linux/nvme.h>: * Copyright (C) 2011-2014 Intel Corporation @@ -16,6 +16,8 @@ #define NVMECMDS_H_CVSID "$Id$" +#include "static_assert.h" + #include <stdint.h> // The code below was originally imported from <linux/nvme.h> include file from @@ -38,6 +40,7 @@ struct nvme_error_log_page { unsigned char vs; unsigned char resv[35]; }; +STATIC_ASSERT(sizeof(nvme_error_log_page) == 64); struct nvme_id_power_state { unsigned short max_power; // centiwatts @@ -56,6 +59,7 @@ struct nvme_id_power_state { unsigned char active_work_scale; unsigned char rsvd23[9]; }; +STATIC_ASSERT(sizeof(nvme_id_power_state) == 32); struct nvme_id_ctrl { unsigned short vid; @@ -127,12 +131,14 @@ struct nvme_id_ctrl { struct nvme_id_power_state psd[32]; unsigned char vs[1024]; }; +STATIC_ASSERT(sizeof(nvme_id_ctrl) == 4096); struct nvme_lbaf { unsigned short ms; unsigned char ds; unsigned char rp; }; +STATIC_ASSERT(sizeof(nvme_lbaf) == 4); struct nvme_id_ns { uint64_t nsze; @@ -163,6 +169,7 @@ struct nvme_id_ns { unsigned char rsvd192[192]; unsigned char vs[3712]; }; +STATIC_ASSERT(sizeof(nvme_id_ns) == 4096); struct nvme_smart_log { unsigned char critical_warning; @@ -190,6 +197,7 @@ struct nvme_smart_log { unsigned int thm_temp2_total_time; unsigned char rsvd232[280]; }; +STATIC_ASSERT(sizeof(nvme_smart_log) == 512); enum nvme_admin_opcode { //nvme_admin_delete_sq = 0x00, diff --git a/smartmontools/os_win32.cpp b/smartmontools/os_win32.cpp index 40b7226b6..e3c39dcb1 100644 --- a/smartmontools/os_win32.cpp +++ b/smartmontools/os_win32.cpp @@ -1,7 +1,7 @@ /* * os_win32.cpp * - * Home page of code is: http://www.smartmontools.org + * Home page of code is: https://www.smartmontools.org * * Copyright (C) 2004-19 Christian Franke * @@ -81,19 +81,6 @@ extern unsigned char failuretest_permissive; // aacraid support #include "aacraid.h" -// Silence -Wunused-local-typedefs warning from g++ >= 4.8 -#if __GNUC__ >= 4 -#define ATTR_UNUSED __attribute__((unused)) -#else -#define ATTR_UNUSED /**/ -#endif - -// Macro to check constants at compile time using a dummy typedef -#define ASSERT_CONST(c, n) \ - typedef char assert_const_##c[((c) == (n)) ? 1 : -1] ATTR_UNUSED -#define ASSERT_SIZEOF(t, n) \ - typedef char assert_sizeof_##t[(sizeof(t) == (n)) ? 1 : -1] ATTR_UNUSED - #ifndef _WIN64 #define SELECT_WIN_32_64(x32, x64) (x32) #else @@ -116,12 +103,12 @@ extern "C" { // SMART_* IOCTLs, also known as DFP_* (Disk Fault Protection) -ASSERT_CONST(SMART_GET_VERSION, 0x074080); -ASSERT_CONST(SMART_SEND_DRIVE_COMMAND, 0x07c084); -ASSERT_CONST(SMART_RCV_DRIVE_DATA, 0x07c088); -ASSERT_SIZEOF(GETVERSIONINPARAMS, 24); -ASSERT_SIZEOF(SENDCMDINPARAMS, 32+1); -ASSERT_SIZEOF(SENDCMDOUTPARAMS, 16+1); +STATIC_ASSERT(SMART_GET_VERSION == 0x074080); +STATIC_ASSERT(SMART_SEND_DRIVE_COMMAND == 0x07c084); +STATIC_ASSERT(SMART_RCV_DRIVE_DATA == 0x07c088); +STATIC_ASSERT(sizeof(GETVERSIONINPARAMS) == 24); +STATIC_ASSERT(sizeof(SENDCMDINPARAMS) == 32+1); +STATIC_ASSERT(sizeof(SENDCMDOUTPARAMS) == 16+1); // IDE PASS THROUGH (2000, XP, undocumented) @@ -143,8 +130,8 @@ typedef struct { #pragma pack() -ASSERT_CONST(IOCTL_IDE_PASS_THROUGH, 0x04d028); -ASSERT_SIZEOF(ATA_PASS_THROUGH, 12+1); +STATIC_ASSERT(IOCTL_IDE_PASS_THROUGH == 0x04d028); +STATIC_ASSERT(sizeof(ATA_PASS_THROUGH) == 12+1); // ATA PASS THROUGH (Win2003, XP SP2) @@ -178,16 +165,16 @@ typedef struct _ATA_PASS_THROUGH_EX { #endif // IOCTL_ATA_PASS_THROUGH -ASSERT_CONST(IOCTL_ATA_PASS_THROUGH, 0x04d02c); -ASSERT_SIZEOF(ATA_PASS_THROUGH_EX, SELECT_WIN_32_64(40, 48)); +STATIC_ASSERT(IOCTL_ATA_PASS_THROUGH == 0x04d02c); +STATIC_ASSERT(sizeof(ATA_PASS_THROUGH_EX) == SELECT_WIN_32_64(40, 48)); // IOCTL_SCSI_PASS_THROUGH[_DIRECT] -ASSERT_CONST(IOCTL_SCSI_PASS_THROUGH, 0x04d004); -ASSERT_CONST(IOCTL_SCSI_PASS_THROUGH_DIRECT, 0x04d014); -ASSERT_SIZEOF(SCSI_PASS_THROUGH, SELECT_WIN_32_64(44, 56)); -ASSERT_SIZEOF(SCSI_PASS_THROUGH_DIRECT, SELECT_WIN_32_64(44, 56)); +STATIC_ASSERT(IOCTL_SCSI_PASS_THROUGH == 0x04d004); +STATIC_ASSERT(IOCTL_SCSI_PASS_THROUGH_DIRECT == 0x04d014); +STATIC_ASSERT(sizeof(SCSI_PASS_THROUGH) == SELECT_WIN_32_64(44, 56)); +STATIC_ASSERT(sizeof(SCSI_PASS_THROUGH_DIRECT) == SELECT_WIN_32_64(44, 56)); // SMART IOCTL via SCSI MINIPORT ioctl @@ -214,8 +201,8 @@ ASSERT_SIZEOF(SCSI_PASS_THROUGH_DIRECT, SELECT_WIN_32_64(44, 56)); #endif // IOCTL_SCSI_MINIPORT_SMART_VERSION -ASSERT_CONST(IOCTL_SCSI_MINIPORT, 0x04d008); -ASSERT_SIZEOF(SRB_IO_CONTROL, 28); +STATIC_ASSERT(IOCTL_SCSI_MINIPORT == 0x04d008); +STATIC_ASSERT(sizeof(SRB_IO_CONTROL) == 28); // IOCTL_STORAGE_QUERY_PROPERTY @@ -266,9 +253,9 @@ typedef struct _STORAGE_PROPERTY_QUERY { #endif // IOCTL_STORAGE_QUERY_PROPERTY -ASSERT_CONST(IOCTL_STORAGE_QUERY_PROPERTY, 0x002d1400); -ASSERT_SIZEOF(STORAGE_DEVICE_DESCRIPTOR, 36+1+3); -ASSERT_SIZEOF(STORAGE_PROPERTY_QUERY, 8+1+3); +STATIC_ASSERT(IOCTL_STORAGE_QUERY_PROPERTY == 0x002d1400); +STATIC_ASSERT(sizeof(STORAGE_DEVICE_DESCRIPTOR) == 36+1+3); +STATIC_ASSERT(sizeof(STORAGE_PROPERTY_QUERY) == 8+1+3); // IOCTL_STORAGE_QUERY_PROPERTY: Windows 10 enhancements @@ -305,15 +292,15 @@ namespace win10 { ULONG Reserved[3]; } STORAGE_PROTOCOL_SPECIFIC_DATA; - ASSERT_SIZEOF(STORAGE_PROTOCOL_SPECIFIC_DATA, 40); + STATIC_ASSERT(sizeof(STORAGE_PROTOCOL_SPECIFIC_DATA) == 40); } // namespace win10 // IOCTL_STORAGE_PREDICT_FAILURE -ASSERT_CONST(IOCTL_STORAGE_PREDICT_FAILURE, 0x002d1100); -ASSERT_SIZEOF(STORAGE_PREDICT_FAILURE, 4+512); +STATIC_ASSERT(IOCTL_STORAGE_PREDICT_FAILURE == 0x002d1100); +STATIC_ASSERT(sizeof(STORAGE_PREDICT_FAILURE) == 4+512); // 3ware specific versions of SMART ioctl structs @@ -346,8 +333,8 @@ typedef struct _SENDCMDINPARAMS_EX { #pragma pack() -ASSERT_SIZEOF(GETVERSIONINPARAMS_EX, sizeof(GETVERSIONINPARAMS)); -ASSERT_SIZEOF(SENDCMDINPARAMS_EX, sizeof(SENDCMDINPARAMS)); +STATIC_ASSERT(sizeof(GETVERSIONINPARAMS_EX) == sizeof(GETVERSIONINPARAMS)); +STATIC_ASSERT(sizeof(SENDCMDINPARAMS_EX) == sizeof(SENDCMDINPARAMS)); // NVME_PASS_THROUGH @@ -378,21 +365,21 @@ typedef struct _NVME_PASS_THROUGH_IOCTL #endif // NVME_PASS_THROUGH_SRB_IO_CODE -ASSERT_CONST(NVME_PASS_THROUGH_SRB_IO_CODE, (int)0xe0002000); -ASSERT_SIZEOF(NVME_PASS_THROUGH_IOCTL, 152+1); -ASSERT_SIZEOF(NVME_PASS_THROUGH_IOCTL, offsetof(NVME_PASS_THROUGH_IOCTL, DataBuffer)+1); +STATIC_ASSERT(NVME_PASS_THROUGH_SRB_IO_CODE == (int)0xe0002000); +STATIC_ASSERT(sizeof(NVME_PASS_THROUGH_IOCTL) == 152+1); +STATIC_ASSERT(sizeof(NVME_PASS_THROUGH_IOCTL) == offsetof(NVME_PASS_THROUGH_IOCTL, DataBuffer)+1); // CSMI structs -ASSERT_SIZEOF(IOCTL_HEADER, sizeof(SRB_IO_CONTROL)); -ASSERT_SIZEOF(CSMI_SAS_DRIVER_INFO_BUFFER, 204); -ASSERT_SIZEOF(CSMI_SAS_PHY_INFO_BUFFER, 2080); -ASSERT_SIZEOF(CSMI_SAS_STP_PASSTHRU_BUFFER, 168); +STATIC_ASSERT(sizeof(IOCTL_HEADER) == sizeof(SRB_IO_CONTROL)); +STATIC_ASSERT(sizeof(CSMI_SAS_DRIVER_INFO_BUFFER) == 204); +STATIC_ASSERT(sizeof(CSMI_SAS_PHY_INFO_BUFFER) == 2080); +STATIC_ASSERT(sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER) == 168); // aacraid struct -ASSERT_SIZEOF(SCSI_REQUEST_BLOCK, SELECT_WIN_32_64(64, 88)); +STATIC_ASSERT(sizeof(SCSI_REQUEST_BLOCK) == SELECT_WIN_32_64(64, 88)); } // extern "C" @@ -912,7 +899,7 @@ static int ata_via_scsi_miniport_smart_ioctl(HANDLE hdevice, IDEREGS * regs, cha } params; char space[512-1]; } sb; - ASSERT_SIZEOF(sb, sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS)-1+512); + STATIC_ASSERT(sizeof(sb) == sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS)-1+512); memset(&sb, 0, sizeof(sb)); unsigned size; @@ -1004,7 +991,7 @@ static int ata_via_3ware_miniport_ioctl(HANDLE hdevice, IDEREGS * regs, char * d IDEREGS regs; UCHAR buffer[512]; } sb; - ASSERT_SIZEOF(sb, sizeof(SRB_IO_CONTROL)+sizeof(IDEREGS)+512); + STATIC_ASSERT(sizeof(sb) == sizeof(SRB_IO_CONTROL)+sizeof(IDEREGS)+512); if (!(0 <= datasize && datasize <= (int)sizeof(sb.buffer) && port >= 0)) { errno = EINVAL; @@ -2027,9 +2014,7 @@ private: int csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info, port_2_index_map & p2i) { // max_number_of_ports must match CSMI_SAS_PHY_INFO.Phy[] array size - typedef char ASSERT_phy_info_size[ - (int)(sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0])) == max_number_of_ports ? 1 : -1] - ATTR_UNUSED; + STATIC_ASSERT(sizeof(phy_info.Phy) == max_number_of_ports * sizeof(phy_info.Phy[0])); // Get driver info to check CSMI support CSMI_SAS_DRIVER_INFO_BUFFER driver_info_buf; @@ -2604,7 +2589,7 @@ bool win_tw_cli_device::open() pout("[\n%.100s%s\n]\n", buffer, (size>100?"...":"")); // Fake identify sector - ASSERT_SIZEOF(ata_identify_device, 512); + STATIC_ASSERT(sizeof(ata_identify_device) == 512); ata_identify_device * id = &m_ident_buf; memset(id, 0, sizeof(*id)); copy_swapped(id->model , findstr(buffer, " Model = " ), sizeof(id->model)); diff --git a/smartmontools/os_win32/vc14/smartctl.vcxproj b/smartmontools/os_win32/vc14/smartctl.vcxproj index d71d8c064..9faacb160 100644 --- a/smartmontools/os_win32/vc14/smartctl.vcxproj +++ b/smartmontools/os_win32/vc14/smartctl.vcxproj @@ -292,6 +292,7 @@ <ClInclude Include="..\..\json.h" /> <ClInclude Include="..\..\nvmecmds.h" /> <ClInclude Include="..\..\nvmeprint.h" /> + <ClInclude Include="..\..\static_assert.h" /> <ClInclude Include="..\popen.h" /> <ClInclude Include="config.h" /> <ClInclude Include="svnversion.h" /> diff --git a/smartmontools/os_win32/vc14/smartctl.vcxproj.filters b/smartmontools/os_win32/vc14/smartctl.vcxproj.filters index d44956c56..8577da519 100644 --- a/smartmontools/os_win32/vc14/smartctl.vcxproj.filters +++ b/smartmontools/os_win32/vc14/smartctl.vcxproj.filters @@ -110,6 +110,7 @@ <ClInclude Include="..\..\nvmeprint.h" /> <ClInclude Include="..\..\dev_intelliprop.h" /> <ClInclude Include="..\..\json.h" /> + <ClInclude Include="..\..\static_assert.h" /> <ClInclude Include="..\..\getopt\getopt_int.h"> <Filter>getopt</Filter> </ClInclude> diff --git a/smartmontools/os_win32/vc14/smartd.vcxproj b/smartmontools/os_win32/vc14/smartd.vcxproj index e53e93175..4f8a0c89b 100644 --- a/smartmontools/os_win32/vc14/smartd.vcxproj +++ b/smartmontools/os_win32/vc14/smartd.vcxproj @@ -310,6 +310,7 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClInclude> + <ClInclude Include="..\..\static_assert.h" /> <ClInclude Include="..\daemon_win32.h" /> <ClInclude Include="..\popen.h" /> <ClInclude Include="..\syslog.h" /> diff --git a/smartmontools/os_win32/vc14/smartd.vcxproj.filters b/smartmontools/os_win32/vc14/smartd.vcxproj.filters index 06cf09792..e833cdf58 100644 --- a/smartmontools/os_win32/vc14/smartd.vcxproj.filters +++ b/smartmontools/os_win32/vc14/smartd.vcxproj.filters @@ -111,6 +111,7 @@ <ClInclude Include="..\..\nvmecmds.h" /> <ClInclude Include="..\..\nvmeprint.h" /> <ClInclude Include="..\..\dev_intelliprop.h" /> + <ClInclude Include="..\..\static_assert.h" /> <ClInclude Include="..\..\getopt\getopt_int.h"> <Filter>getopt</Filter> </ClInclude> diff --git a/smartmontools/static_assert.h b/smartmontools/static_assert.h new file mode 100644 index 000000000..a240b2cb7 --- /dev/null +++ b/smartmontools/static_assert.h @@ -0,0 +1,27 @@ +/* + * static_assert.h + * + * Home page of code is: https://www.smartmontools.org + * + * Copyright (C) 2019 Christian Franke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef STATIC_ASSERT_H +#define STATIC_ASSERT_H + +#define STATIC_ASSERT_H_CVSID "$Id$" + +#if __cplusplus >= 201103 || _MSVC_LANG >= 201103 +#define STATIC_ASSERT(x) static_assert((x), #x) +#elif __STDC_VERSION__ >= 201112 +#define STATIC_ASSERT(x) _Static_assert((x), #x) +#elif __GNUC__ >= 4 +#define STATIC_ASSERT(x) typedef char static_assertion[(x) ? 1 : -1] \ + __attribute__((unused)) +#else +#define STATIC_ASSERT(x) typedef char static_assertion[(x) ? 1 : -1] +#endif + +#endif // STATIC_ASSERT_H -- GitLab