I'm trying to run a LLVM pass on some C code and need to remove Constants from a ConstantArray. I have a GlobalVariable with said ConstantArray as initializer.
Deleting entries works usingF->replaceAllUsesWith(llvm::UndefValue::get(F->getType())) and F->dropAllReferences() but that's not acceptable - I can't change the code using the array and it stops processing the array after encountering the first NULL value.
Is there any easy way to simply drop Constants from a ConstantArray or do I have to create a new array without the respective entries I want to remove?
Related
I'm new to Lua (language version 5.4 if it matters, there doesn't seem to be a tag for that version on SO yet) and I'm trying to find the most idiomatic way to implement iteration (for loop) over a userdata object.
The Lua 5.4 Reference Manual says regarding a loop statement for var_1, ···, var_n in explist do body end:
The loop starts by evaluating explist to produce four values: an iterator function, a state, an initial value for the control variable, and a closing value.
The idiomatic way to loop seems to be using the pairs(t) function. This also works for userdata via the __pairs metamethod. However:
If t has a metamethod __pairs, calls it with t as argument and returns the first three results from the call.
Why only three instead of four? If I have a complex userdata object that needs to allocate some resource for a loop, I'll need that closing value so I know when to deallocate that resource in case the loop ends early, right? Does that mean I cannot use pairs in such a case or am I missing something?
I could of course provide a new function, say pairs4, but that doesn't seem to be very idiomatic.
Because that's how it has always worked since at least Lua 5.0. pairs always returned 3 values because for previously only took 3 values.
"to-be-closed variables" are a new feature of Lua 5.4, as is the fourth value for generic for. Why pairs wasn't updated to match is unknown. It is possible that pairs returns all of the values from the __pairs metamethod, but I haven't looked at the implementation to verify this.
In this case, I would suggest writing a pairs_close that returns 4 arguments from the __pairs metamethod.
I am currently working on a Character Customization System where a HUDLayout dynamically create Widgets based on a set of Skins available for the Character Selected. A Skin is represented as a Struct called MaterialInstanceContainer and holds a TArray. Player can mix and match their selection according to the Body Parts they select. In order to achieve the final result, I want to create a TMap<string, MaterialInstanceContainer> so that I can map each BodyParts available for selection with the individual material instance targeting the same BodyPart.
ISSUE: My issue is as follow, when I try to foreach over my collection of Material Instances inside my Container, I do a string comparison and if the output is valid, I can then break my struct to access the Material Instance Array and ADD to it however, at the very end of the process, the length of the array inside Material Container is still at zero.
How can I add a new entry in the array that my Material Container Struct hold?
Thanks!
enter image description here
The issue here is actually pretty straight forward: in Blueprints when you 'Find' a member of Map you are not getting it by-reference, instead you get the copy.
This is exactly what happens at the end of your nested loop: You get a copy, you add item to it, and when another iteration kicks-in the copy gets terminated.
And here on my side it returns exactly the same result as expected:
The fix for that would be easy:
After editing a Copy, you can overwrite the Map member by its copy (via 'Add' node).
But in your case it will be more tricky. You cannot just plug the same BreakStruct/Array node that you just used because it would call whole Find sequence again which creates another copy. Look
If you are confused. This code actually looks like this for Unreal's point of view.
So you have to store the the Struct in local variable first, then perform any operations on it and after everything is done - overwrite the Map member by its locally stored copy. And the result is
Map member gets overwritten every time and everything is as it should be.
Well, almost... For some reason your code is stored in Macro. I think you have to change it to a Function to be able to create local struct variable. But it shouldn't be a problem in this specific case because in your code there is no logic that needs to be done in macro.
Hope, it helps
I've been following the guide on Exceljet for how to create a recursive LAMBDA function that removes all numbers from a string. For example, A1B2C3D4E5 becomes ABCDE.
The only thing I wanted differently was to have the string containing the character omissions stored inside the function rather than the cell. So, I took away the chars parameter from the opening line and used the LET function to store the string.
The problem is I keep getting a #VALUE! error and can't work out why.
=LAMBDA(str,sub,
LET(chars,"0123456789",
IF(chars="",str,
ReplaceChars(
SUBSTITUTE(str,LEFT(chars),sub),
MID(chars,2,LEN(chars)-1),
sub
)
)
))
A nested LET() in a recursive LAMBDA() is going to be troublesome since every time you'd use the variable in the recursion you'd start from scratch. Replacing characters will therefor never stop (if my interpretation of this is correct). But in your case you don't even need to make a recursive LAMBDA() to replace numbers, for example:
=LAMBDA(str,LET(X,MID(str,SEQUENCE(LEN(str)),1),CONCAT(IF(ISNUMBER(X*1),"",X))))
Core of this function is now:
=LET(X,MID(A1,SEQUENCE(LEN(A1)),1),CONCAT(IF(ISNUMBER(X*1),"",X)))
which can be used outside of LAMBDA() just fine. We can even replace this with
=LET(X,MID(A1,SEQUENCE(LEN(A1)),1),CONCAT(IF(ISNUMBER(FIND(X,"0123456789")),"",X)))
to do the same thing with any character you want to replace.
Now you can call =REPLACECHARS(A1). However, IMHO the beauty of the use of variables is now lost and the original approach (for example here would have my personal preference.
I am being passed an array from a C program that does not include the size of the array; that is, it just passes a pointer to the array. The array is a generic type <Item>. How can I determine the end of the array in order to detect a buffer overflow?
I tried iterating through the array until I received something that wasn't an <Item>. That worked most of the time but sometimes the nonsense at the end Would be of type <Item>. I am using C and calling a function from an external class I had no deal in developing. <Item> is a struct with multiple references to other arrays (sort of like a linked list).
EDIT:
The api stated that the array was intended to be a read-only version. The problem is I cannot read it if I do not know the size. It doesn't appear there is a sentinel value. There is a random comment stating that if the size is needed use sizeOf (array)/sizeOf (Item) which doesn't work. It was developed by a team that no longer works here. The problem is other code already relies on this C code and I cannot change it without fear of ruining other code.
It is not possible to determine the end of an array based on just a pointer to an element of that array.
I tried iterating through the array until I received something that wasn't an <Item>
It's also not possible to determine whether particular memory location contains an object of particular type - or whether it contains any object. Even if you could, how would you determine if the object that you find is really part of the array and not just a separate <Item> object that happens to be there?
A possible solution is to use a sentinel value to represent the end of an array. For example, you could define the interface such that <Item>.member == 0 if and only if that is the last element of the array. This is similar to how null-terminated strings work.
If all you have is a pointer and no size or known "end-of-array" marker (sentinel) in the data, then you have an impossible situation. There is no way in that case to determine the size/end of the passed array.
I have a UserForm with a ListBox for the user to select values. Those values are populated in UserForm_Initialize() via a function call to the base module, which returns an array as variant. This works without problems.
If the user selects some values and presses a button, the buttons Click event calls another function in the base module to pass on the user-entered array and compute things. This does not work at all. The value received in the base module is always nonexistent (not even null, but I don't know the correct VBA term, nothing is there at all).
Things I have tried so far:
Passing all arguments ByVal: Did not make a difference
Using global shared variables: This did work, but I don't want to rely on them if all I do is pass a single array to a single function. This also introduces state into the code which has to be managed, especially when reusing the function
Accessing the functions by full qualifiers: Did not make a difference. The functions are found and executed correctly, but the argument variables are empty, therefore the functions fail later on when doing the calculations.
My question is: How can I pass arrays from UserForms to Modules (not vice versa) without relying on global variables and without losing the array content?
This question may be related to this question about passing a String from Form to Module, but the accepted answer does not help in my case (using global variables).
When adding the code as requested in the comments, I stumbled upon that fact that I could print the content of the array, but it would not show anything in the debugger and the size would be 0.
The size issue was because I used Len(array) instead of Application.CountA(array) and I had a leftover On error resume next from earlier still in the code, which meant that no error was raised and size was always set to zero... This was the reason for the strange behaviour.