I'm trying to solve Can Xcode tell me if I forget to include a category implementation in my target?, and I came up with the following solution:
NSObject+Foo.h
extern int volatile canary;
void canaryCage() {
canary = 0;
}
NSObject+Foo.m
int canary = 0;
Now, if I #import "NSObject+Foo.h" in a source file, I'll get a linker error if that NSObject+Foo.m wasn't also included in my target.
However, every time I #import "NSObject+Foo.h" I generate a duplicate _canaryCage symbol. I can't use __COUNTER__ because I only #import "NSObject+Foo.h" in implementation files. I need canaryCage to be unique across my whole symbol table.
I need something like:
#define CONCAT(x, y) x##y
#define CONCAT2(x, y) CONCAT(x, y)
extern int volatile canary;
void CONCAT2(canaryCage, __RANDOM__)() {
canary = 0;
}
This way, if I have source files like:
Bar.m
#import "NSObject+Foo.h"
Baz.m
#import "NSObject+Foo.h"
I'll get symbols like _canaryCage9572098740753234521 and _canaryCage549569815492345, which won't conflict. I also don't want to enable --allow-multiple-definition in ld because I want other duplicate symbol definitions to cause an error. I don't want to use canaryCage for anything but a marker that I forgot to link a source file whose header I #imported.
If you make it static, each translation unit will get its own copy, and everything else should work the way you want it to - no preprocessor gymnastics required.
static void canaryCage()
{
canary = 0;
}
This answer was close, but it resulted in canaryCage being optimized away because it was dead code.
Solution:
NSObject+Foo.h
extern int canary;
__attribute__((constructor)) static void canaryCage() {
canary = 0;
}
NSObject+Foo.m
int canary = 0;
Unfortunately, this adds some overhead every time the category is imported, but the overhead is very minimal. If anyone knows a way to prevent canaryCage from being stripped, I'll happily mark their answer as correct.
Related
c++ : Run time error is happened with error message like this:
RevStrings1->Height of reading included in error: The property is write-protected.
RevStrings1->Height の読み込中のエラー : プロパティは書き込み禁止です.
I'm using c++ builder 3.
This source code can be successfully compiled
setting library, include path and etc.
But run time error is happened.
I guess that this problem is about property read & write.
How can I simplly fix the problem ?
A variable RevStrings1 is created by a class TRevStrings.
//---------------------------------------------------------------------------
#ifndef RevStringsH
#define RevStringsH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class PACKAGE TRevStrings : public TStringGrid
{
private:
// void __fastcall SetWidth(int W);
// int __fastcall GetWidth(void);
// int FColCount ;
int FRowCount;
int FFixedCols ;
int FFixedRows ;
int FDefaultColWidth ;
int FDefaultRowHeight ;
int FHeight;
// int FWidth;
int FScrollBars;
int FMaxLength;
bool ColColors[24];
protected:
public:
__fastcall TRevStrings(TComponent* Owner);
void __fastcall DrawCellText(TRect ARect,int ALeft,String S);
virtual void __fastcall DrawCell(int ACol, int ARow,const Windows::TRect &ARect, TGridDrawState AState);
void __fastcall SetColor_Col(int Col,int Row);
void __fastcall SetColorFlag(int Col,bool flag);
bool __fastcall GetColorFlag(int Col);
void __fastcall SetEditText(int ACol, int ARow,const System::AnsiString Value);
void __fastcall Clear(bool ALLorONE,int Position);
void __fastcall DblClick(void);
__published:
// __property int ColCount = {read = FColCount};//FColCount};
__property int RowCount = {read=FRowCount};
__property int FixedCols = {read=FFixedCols};
__property int FixedRows = {read=FFixedRows};
__property int DefaultColWidth = {read=FDefaultColWidth};
__property int DefaultRowHeight = {read=FDefaultRowHeight};
__property int Height = {read=FHeight};
// __property int Width = {read=GetWidth,write=SetWidth};
__property int ScrollBars = {read=FScrollBars};
__property int MaxLength = {read=FMaxLength,write=FMaxLength};
/*
*/
};
//---------------------------------------------------------------------------
#endif
never heard of TRevStrings before
so it is either BCB 3 discontinued stuff (my BDS2006 does not have it at disposal) or you have some 3th party custom package installed but the header file suggest it is based on TStringGrid so if below text does not work for it then you can switch to TStringGrid instead.
in TStringGrid
size properties are accessible normaly:
StringGrid1->Height=256;
StringGrid1->Width=128;
if you want to have size-able col/rows then do not forget to open Options property and set goRowSizing,goColSizing to true and starting sizes are DefaultColWidth,DefaultRowHeight. Here example of usage
// resize the grid
StringGrid1->Height=128;
StringGrid1->Width=256;
// access to Cell AnsiStings
StringGrid1->Cells[0][0]="(0,0)";
StringGrid1->Cells[1][1]="(1,1)";
StringGrid1->Cells[1][2]="(1,2)";
StringGrid1->Cells[2][1]="(2,1)";
// resizing row/col
StringGrid1->RowHeights[0]=15;
StringGrid1->RowHeights[1]=20;
StringGrid1->ColWidths[0]=20;
StringGrid1->ColWidths[1]=15;
As your class is derived from this so this should work also for it if not the there are more possibilities:
you have unrelated bug somewhere
overwriting what you should not damaging the C++ engine your App is running on or have memory leak somewhere or your memory manager is invalidated see
bds 2006 C hidden memory manager conflicts
but that is probably not the case or you are calling VCL/Winapi visual stuff from threads.
To check for all this:
create empty application, add your TRevString and try to set its height on runtime. If no error occurs you have a bug somewhere if error occurs then:
this component is not able to resize on runtime this way
try to use functions like SetSize,SetBounds instead or place the component on some panel align to Client and resize panel
if even this does not help switch to standard TStringGrid
you can also try to cast you RevString to StringGrid first
((TStringGrid*)(RevString1))->Height=25;
Borland compilers sometimes get weird
few times (around 10) over the years I use BCB/BDS the compiler sometimes compile wrongly. The app is running but some code gets distorted or discarted so what helps?
close IDE or even restart Windows
delete all map,obj,tds temp files prior to compiling rebuilding
sometimes is needed that you add empty line of code or swap 2 lines of code
Identifiers/Names collisions
if you name your stuff in similar way to VCL functions then you ask for problems usual error is to name function Draw() ... (use draw() instead and you are fine)
for big projects
if you add your source code as new unit to project instead of just include it (it is present in Object Manager) then in big projects you will got big problems. It looks like units are compiled differently then normal included files in units are expected Formulars and other VCL stuff components so if you got your own non visual classes as units they sometimes stop working as expected creating weird behavior (even your error could be caused by it).
I observe this on BCB5 and BDS2006. In BCB3,BCB4 I did not make big enough projects to spot this and BCB6 is so buggy so its unusable with big projects anyway. By big projects I mean > 1 MB of pure C++ code
The error is self-explanatory - the Height property of the RevStrings1 object is not allowing its value to be assigned. This is evident by looking at the declaration of the Height property in the TRevStrings class:
__property int Height = {read=FHeight};
TRevStrings is going out of its way to make the Height property read-only, overriding the native read-write Height property that is inherited from TControl:
__property int Height = {read=FHeight, write=SetHeight, nodefault};
This is odd for TRevString to do, as it is a visual component that needs to be sizable. Unless it requires a specific height that the user cannot change (in which case declaring the Height property as read-only is not the correct way to handle that - the component should override the virtual SetBounds() method instead and just ignore any new Height value being assigned).
That being said, the reason you see the error at run-time is because the IDE is storing the design-time Height value of the RevStrings1 object in the parent Form's DFM resource at compile-time. That is why you are not finding any RevStrings1->Height in your code - it is coming from the Form Designer instead. The TRevStrings class is not overriding DFM behavior for the Height property, so when the VCL's DFM streaming system parses the Form's DFM resource at run-time, it sees the stored Height value and detects that the object's Height property is actually read-only, and so throws an exception to cancel DFM streaming (and thus the Form's construction).
This is a bug in the TRevStrings implementation. At the very least, if the author had wanted to prevent the Height from being streamed (thus preventing the run-time error), the Height property should have been declared like this instead:
__property Height = {read=FHeight, stored=false};
On a side note, most of the TRevStrings data members (FColCount, FRowCount, FFixedCols, FFixedRows, etc) should never have been declared at all, but instead should have been inherited from the base TStringGrid class.
Whoever wrote this component clearly did not know what they were doing.
I am trying to write some code that interacts with an USB device in Objective C, and I got stuck on setting the callback function for incoming reports. In my case it's an IOKIT function but I think the problem is more general as I (apparently) don't know how to correctly set a C callback function in Objective-C. I've got a Class "USBController" that handles the io functions
USBController.m:
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDLib.h>
#import "USBController.h"
static void Handle_IOHIDDeviceIOHIDReportCallback(
void * inContext, // context from IOHIDDeviceRegisterInputReportCallback
IOReturn inResult, // completion result for the input report operation
void * inSender, // IOHIDDeviceRef of the device this report is from
IOHIDReportType inType, // the report type
uint32_t inReportID, // the report ID
uint8_t * inReport, // pointer to the report data
CFIndex InReportLength) // the actual size of the input report
{
printf("hello"); //just to see if the function is called
}
#implementation USBController
- (void)ConnectToDevice {
...
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
...
}
...
#end
All the functions are also declared in the header file.
I think I did pretty much the same as what I've found here, but it doesn't work. The project compiles nicely and everything works up till the moment there is input and the callback function is to be called. Then I get an "EXC_BAD_ACCESS" error. The first three arguments of the function are correct. I'm not so sure about the context..
What did I do wrong?
I am not sure at all that your EXEC_BAD_ACCESS depends on your callback. Indeed, if you say that it is called (I suppose you see the log) and since it only logs a message, there should be no problem with this.
EXEC_BAD_ACCESS is caused by an attempt to access an already deallocated object. You can get more information in two ways:
execute the program in debug mode, so when it crashes you will be able to see the stack content;
activate NSZombies or run the program using the performance tool Zombies; this will tell you exactly which object was accessed after its deallocation.
I know how to fix this. When calling this:
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
You don't include the code for the creation/type of the value called report. However the method name "Handle_IOHIDDeviceIOHIDReportCallback" comes from an Apple document where there is an error in the creation of the report value. https://developer.apple.com/library/archive/technotes/tn2187/_index.html
CFIndex reportSize = 64;
uint8_t report = malloc( reportSize ); // <---- WRONG
IOHIDDeviceRegisterInputReportCallback( deviceRef,
report,
reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,
context );
Instead do this:
uint8_t *report = (uint8_t *)malloc(reportSize);
I am trying to copy the doxygen of the initial value of a static variable to the top of my code in the \file block. That is, in something like this:
#include <iostream>
/*! \file Test.cxx
* This is my program.
* \copydetails HelpText
*/
/*! \var
* This is my static string.
*/
static std::string HelpText = "Calculate the average magnitude of the vectors in a vector image.\n\n\
Usage:\n\
-in InputVectorImageFileName\n";
int main()
{
return 0;
}
I would want the "Usage" string to appear in the main file documentation. As you can see I tried \copydoc but it only seems to copy the comment above the static variable, not the initial value. Note that the initial value appears properly in the variable's documentation.
Any suggestions?
Thanks.
Sounds like your MAX_INITIALIZER_LINES config in your doxyfile is either 0 or too small. Just give it a sensible value.
I use this code to set my constants
// Constants.h
extern NSInteger const KNameIndex;
// Constants.m
NSInteger const KNameIndex = 0;
And in a switch statement within a file that imports the Constant.h file I have this:
switch (self.sectionFromParentTable) {
case KNameIndex:
self.types = self.facilityTypes;
break;
...
I get error at compile that read this: "error:case label does not reduce to an integer constant"
Any ideas what might be messed up?
For C/C++ and Objective-C must the case statement have fixed values - "reduced to an integer (read value)" at compile time
Your constants is not a real "constant" because it is a variable and I imagine it can be changed through a pointer - ie &KNameIndex
Usually one defines constants as enum
enum {
KNameIndex = 0,
kAnotherConstant = 42
};
If you would use C++, or Objective-C++ (with .mm as file extension) you could use a const statement as
const int KNameIndex = 0;
You can use
#define KNameIndex 0
...
switch (self.sectionFromParentTable) {
case KNameIndex:
self.types = self.facilityTypes;
break;
...
and it should work.
Just had the same problem and I decided to go with #define rather than enum. Works for me™ ;-)
This is a stab in the dark because I haven't used Cocoa / ObjC in a long time now, but is the member variable sectionFromParentTable not of int type?
I have not worked with Objective C, but I'd try chucking the 'extern'. At least if this were C++, the Constants.m file would not be part of the compilation unit of Other.m, so the value of KNameIndex would be unknown to the compiler. Which would explain the error; an unknowable value can't be a constant.
Does putting the definition, not just the declaration, in the Constants.h file help?
I think you are stuck with using a const int instead of a const NSInteger as switch only works with built in integral types. (not sure about your syntax with const flipped around after the type).
Take a look at the related question: Objective-C switch using objects?
The offsetof macro seems not to work under C++/CLI.
This works fine in unmanaged C++, but throws "error C2275: 'Entity' :illegal use of this type as an expression" error in CLI.
struct Property{
char* label;
PropertyTypes type;
unsigned int member_offset;
unsigned int position;
unsigned char bit_offset;
};
struct Entity{
...
bool transparent;
...
};
Property property = {"Transparent",
TYPE_BOOL,
offsetof(Entity, transparent),
0,
0}; // C2275 HERE
Does CLI have some replacement?
My guess would be that the compiler message boils down to: "offsetof" is not a known macro and if it was a function its parameters must not contain a typename.
Edit: As somebody pointed out in the comments, offsetof is actually part of the std lib. So what's missing is probably just
#include <cstddef>
Alternatively, you can use this macro implementation (taken from Win32/MFC headers):
#ifdef _WIN64
#define OFFSET_OF( s, m )\
(size_t)((ptrdiff_t)&reinterpret_cast<const volatile char&>((((s*)0)->m)) )
#else
#define OFFSET_OF( s, m )\
(size_t)&reinterpret_cast<const volatile char&>((((s*)0)->m))
#endif
Standard C++ already has an alternative; &Entity::transparent. You'll probably want to use templates when redesigning the Propery class. The type of a pointer-to-member is non-trivial.
You will need to provide the type of the object you are assigning to. Looks like there is some type-mismatch for the member in question.
See this for sample usage.
Just a shot in the dark and without a chance to double-check this - should
offsetof(Entity, transparent),
perhaps rather read
offsetof( struct Entity, transparent ),
???