PasteboardPutItemFlavor Null passed to a callee that requires a non-null argument - xcode

I know there are plenty of questions asking about how to solve "Null passed to a callee that requires a non-null argument", but I really can't seem to find a solution for my problem.
I use a function called PasteboardPutItemFlavor in my code. It compiles alright if I set the deploy target to 10.12 built against macSDK10.12. After I set the deploy target to 10.8, but still compile it against macSDK10.12, I got an error on PasteboardPutItemFlavor call. The error message is "Null passed to a callee that requires a non-null argument". What does this error mean? kPasteboardFlavorNoFlags is defined as 0, changing to other constant value doesn't change anything.
How do I solve this error with 10.8 as deploy target and compile against 10.12?
PasteboardPutItemFlavor(
m_pboard,
nullptr,
flavorType,
dataRef,
kPasteboardFlavorNoFlags);
The function declaration is
OSStatus PasteboardPutItemFlavor(PasteboardRef inPasteboard, PasteboardItemID inItem, CFStringRef inFlavorType, CFDataRef inData, PasteboardFlavorFlags inFlags);

I looked into the header file from 10.12 SDK. The header file is warped with nonnull macro. So any pointer with that macro would be declared as nonnull. In my case is the nullptr parameter. I simply create a local variable and set to 0 then pass it in PasteboardPutItemFlavor. That solves the error.

Related

[gdb][script] Syntax change from version 6.5 to 10.2 gdb gcc toolchain

The old syntax in the 6.5.0 that works for this statement:
set {int}(&FlashBufferStart+$EraseCnt*2+0) = 0x1000
This would mean placing value 0x1000 into into into the allocated address.
With the new 10.2.0 this sentence will result an error:
Cannot perform pointer math on incomplete type "<data variable, no debug info>"
I have tried using type casting parenthesis, {int} , {void*}, or value might just ended totally different, I have seen similar post for this error but it didn't solve the issue. Any idea?
With the new 10.2.0 this sentence will result an error:
It appears that GDB doesn't know the type of FlashBufferStart.
GDB-6.5 probably assumed that this is a char (or maybe in int), and silently performed arithmetic corresponding to the assumed pointer type.
GDB=6.10 is telling you that it doesn't understand what you want it to do instead.
Solution: cast &FlashBufferStart to appropriate pointer type, so GDB knows what you want.

tslint: How to make sure that a variable is not undefined?

As per the following screenshot, the TsLint is claiming that a variable might be undefined which is not assignable to a function's parameter.
But I have already checked and make sure that it's not undefined above passing it as the function's parameter.
Why does TsLint is still claiming that the variable might be undefined?
I can dismiss that warning by changing the code to:
clearTimeout(saveDraftTimer.current as unknown as number)
but it looks ugly, any better suggestion?
const saveDraftTimer = useRef<number | undefined>(undefined);

Why Microsoft Error Message uses the word "Token"?

I purposely set a bad path for a CreateDirectory call so that my exception handling code would execute:
I am not sure if this is off topic, but you might have more experience with this. Why is the error text:
An attempt was made to reference a token that does not exist.
Why are they using the word token instead of file or folder?
I will close the question if off topic.
The return value of GetLastError is: 123
According to here:
ERROR_INVALID_NAME
123 (0x7B)
The filename, directory name, or volume label syntax is incorrect.
Now that message makes sense. So why is my Windows 10 showing the other message?
There is no issue with the call to FormatMessage. It works as advertised. However, you aren't passing in the value 123 (ERROR_INVALID_NAME). You are passing 1008 (ERROR_NO_TOKEN), by accident, due to calling GetLastError at the wrong time. GetLastError has a strong requirement:
You should call the GetLastError function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError with a zero when they succeed, wiping out the error code set by the most recently failed function.
It's fairly straightforward to satisfy this in C. With C++, things get more complicated, with all the invisible code the compiler generates. The code in question apparently captures the calling thread's last error code only after it enters the CWin32FileError c'tor. That's too late.
Based on the assumption that GetWorkingPath() returns a CString instance by value, and CWin32FileError takes its arguments as CString const&, this is what happens behind the scenes:
if (!CreateDirectory(GetWorkingPath() + _T("whatever"), nullptr))
GetWorkingPath() constructs a temporary CString instance.
operator+(CString const&, LPCTSTR) constructs yet another temporary CString instance, concatenating both inputs.
operator LPCTSTR() is implicitly invoked on the temporary constructed in step 2.
CreateDirectory is called and returns.
Important: The destructor of the temporary created in step 2 is called.
Important: The destructor of the temporary created in step 1 is called.
Steps 5 and 6 are fatal already, potentially changing the calling thread's last error code. And yet, there's even more code getting in the way:
CWin32FileError e(_T("whatever"),
GetWorkingPath() + _T("whatever"));
Important: _T("whatever") triggers CString's conversion constructor (CString(LPCTSTR)), producing a temporary.
Important: GetWorkingPath() constructs a temporary, invoking CString's copy-c'tor.
Important: operator+(CString const&, LPCTSTR) constructs yet another temporary.
The CWin32FileError c'tor finally runs, presumably calling GetLastError.
This adds another 3 candidates (at least) that can modify the calling thread's last error code. To solve this, you're going to have to make sure, that absolutely no code runs in between a failed Windows API call and the call to GetLastError.
To do this, you're going to have to get rid of the temporaries, and move capturing of the last error code outside the CWin32FileError c'tor. A simple solution to the former would be to construct the path name up front, e.g.
auto path_name{ GetWorkingPath() + _T("whatever") };
auto path_name_strptr{ path_name.GetString() };
if (!CreateDirectory(path_name_strptr, nullptr))
// ...
(or use an init-statement in the if statement to limit the scope, if you are using C++17). Either way, your very next call must be GetLastError to capture the last error code while it is still meaningful. However you pass that value into CWin32FileError's c'tor, or which argument types it uses, is up to you. But you cannot rely on that c'tor to capture the last error code for you.

Call a block from XCode's debugger

Can I call a block from the XCode debugger? I just tried:
po zoomCurve(0)
Which has the type:
typedef CGFloat (^STAnimationCurveBlock)(CGFloat t);
And the debugger says:
error: called object type 'STAnimationCurveBlock' (aka '__block_literal_generic *') is not a function or function pointer
error: 1 errors parsing expression
As described in this answer, the debugger doesn't seem to know the type of the block. You need to cast the block to its type. In the specific case you have there:
po ((CGFloat(^)(CGFloat))zoomCurve)(0.9)
For some reason, casting to the typdef type also doesn't work, and gives the same error. Specifically, this will give the same error:
po ((STAnimationCurveBlock)zoomCurve)(0.9)

Incompatible integer to pointer conversion assigning to 'BOOL

I just inherent a new app from a previous programmer and keep on running into a "Incompatible integer to pointer conversion assigning to 'BOOL *' (aka 'bool *') from 'BOOL' (aka 'bool') ".
Code like such as
_backButtonPressed = YES;
_isEdited = YES;
come up with the same error. I tried *(_backButtonPressed) = YES; and
*_backButtonPressed = Yes, but both scenarios crashes the program.
Program still work if I leave it alone, but I wanted to keep the code clean. Any suggestion?
My guess is that the two variables in question were declared incorrectly. For example, _backButtonPressed is probably declared as
BOOL* _backButtonPressed;
but should be
BOOL _backButtonPressed;
The crash occurs because _backButtonPress is not a pointer: if it was, there would be a statement like
_backButtonPressed = (BOOL*)malloc(sizeof(BOOL));
somewhere. If this was not done before you try to assign to
*(_backButtonPressed), then you will see a crash.
It is easy to make the mistake of declaring BOOL* instead of BOOL, because Cocoa objects are always declared with the *
I recommend that you fix the declarations. I am pretty sure everything will work if you do that.

Resources