As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/
We're funding a new Acquisitions Incorporated series on Kickstarter right now! Check it out at https://www.kickstarter.com/projects/pennyarcade/acquisitions-incorporated-the-series-2

Giant Programming Clusterfuck++

1212224262763

Posts

  • bowenbowen How you doin'? Registered User regular
    edited May 2009
    I hate double pointers, I hate them so much.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • InfidelInfidel Heretic Registered User regular
    edited May 2009
    Zack your explanations are not quite correct, sorry.

    Alright, time for a pointer/memory primer!

    Let's look at how C views memory. It basically just assumes you have a flat linear space of bytes for all the memory you have access to (flat memory model) kind of like an array which you are hopefully familiar with.

    memory0.gif

    Let's say the C compiler allocated space for an integer I declared in this memory space.
    int var = 7;
    

    An integer will probably be 32 bit, so 4 bytes of memory. Let's say it put this at memory location 4.

    memory1.gif

    Now normally we don't care right? We just access this integer by the variable name we gave it. If we want to use it, we can just reference var, to assign the value we just have var = var + 1, etc. How it is stored in memory is irrelevant to what we're doing, and so it makes sense to ignore these details.

    But sometimes you need to care.

    First off, let's say I want to know where var is stored in memory. I know it's 7, but what is the address of where that 7 is stored?
    int *pointer = &var;
    

    &var uses the address-of operator &, which should be easy to see that it is the number 4. What is the int * declaration? The * just means we're declaring a pointer type, the rest is telling the compiler what kind of thing we are pointing to. So int *pointer is saying "pointer holds the address of an integer variable" and the above code statement demonstrates that.

    So pointer is just another variable in your program now, holding the value of 4. For the sake of the example let's say this variable is itself stored in memory location 8. A pointer is always a fixed size based on your architecture/memory model, because no matter what kind of data you are pointing to, it's always representing an address. In most systems we're using 32-bit addressing, so we'll just assume for this that all pointers are 4 bytes to store.

    memory2.gif

    Now let's see what happens with the following examples. We'll use the indirection operator * here.
    pointer = 14;
    

    We end up with memory looking like:

    memory3.gif

    which is not likely what we intended. We wanted to change the integer that we're pointing to, var, so do it like so.
    *pointer = 14;
    

    memory4.gif

    The indirection operator is the counterpart to the address-of operator. If & takes a variable and gives us a number representing the location of it in memory, then * takes a memory location and turns it into a variable again. That's why we declare pointers with type, so that we know what kind of variable we're talking about.

    *pointer = 14 starts by looking up the value of the pointer variable. It is 4. So we have *(4) and the compiler knows to treat this as "an integer at address 4", which we can then assign the value 14 to like any other integer variable.

    How does it know to treat address 4 like an integer? Because we declared pointer as int *pointer.

    The operators work the same when not on the lefthand-side of an assignment. If I wanted to access the value stored in var, I could do either of these statements.
    printf("%d", var);
    printf("%d", *pointer);
    

    If I do something like the following, it will work as expected sorta, and it should compile but will generate warnings because you likely didn't mean to do it.
    printf("%d", pointer);
    

    This would print out 4 instead of the desired 14, because it's treating that address as just any other number when you don't have the indirection operator.
    I'll expand on this some more but I have to take care of other things at the moment and I don't want to lose this post in the meantime.

    Infidel on
    OrokosPA.png
    bowenTofystedethEcho
  • ObsObs __BANNED USERS regular
    edited May 2009
    now discuss pointers in relation to threading.

    Obs on
  • InfidelInfidel Heretic Registered User regular
    edited May 2009
    Obs wrote: »
    now discuss pointers in relation to threading.

    now please read the title of the thread :winky:

    Infidel on
    OrokosPA.png
  • ZackSchillingZackSchilling Registered User regular
    edited May 2009
    Revised. I hope it's right. Sorry about the bad info initially. I've been working far too much with Python. Ask me about mutable vs immutable!

    ZackSchilling on
    ghost-robot.jpg
  • ObsObs __BANNED USERS regular
    edited May 2009
    Infidel wrote: »
    Obs wrote: »
    now discuss pointers in relation to threading.

    now please read the title of the thread :winky:

    Which begs the question,

    Will the next thread title just be another Beginner Programming Thread?

    Not if I have anything to do with it. Over the coming days I'm going to gather some of the best op-makers in the tech tavern to create the Intermediate Programming Thread that will eventually replace the beginner one, and it will cover more advanced topics like threading or the upcoming OpenCL standard.

    There's no use in letting this forum stay stuck in Beginner Programming hell. And maybe it will finally encourage some of the stragglers to finally pursue more advanced interests or cowboy up and finally learn shit to participate with their forum peers.


    And who knows, if it takes off then maybe in a more distant future there will even be an Advanced Programming Thread.

    Obs on
  • jackaljackal Fuck Yes. That is an orderly anal warehouse. Registered User regular
    edited May 2009
    Obs wrote: »
    Infidel wrote: »
    Obs wrote: »
    now discuss pointers in relation to threading.

    now please read the title of the thread :winky:

    Which begs the question,

    Will the next thread title just be another Beginner Programming Thread?

    Not if I have anything to do with it. Over the coming days I'm going to gather some of the best op-makers in the tech tavern to create the Intermediate Programming Thread that will eventually replace the beginner one, and it will cover more advanced topics like threading or the upcoming OpenCL standard.

    There's no use in letting this forum stay stuck in Beginner Programming hell. And maybe it will finally encourage some of the stragglers to finally pursue more advanced interests or cowboy up and finally learn shit to participate with their forum peers.


    And who knows, if it takes off then maybe in a more distant future there will even be an Advanced Programming Thread.

    Nothing says "Intermediate" like "concurrent programs running across heterogeneous hardware."

    jackal on
  • InfidelInfidel Heretic Registered User regular
    edited May 2009
    I think it's more that this is a gaming comic forum that we're only covering beginner stuff, we're not really the place to go for more advanced topics.

    And honestly the advanced topics you should be looking at references and courses or something like that, not a thread. This is a pretty good place to come though if you're just a casual person interested in getting into programming, likely due to video games and other computer activities.

    Infidel on
    OrokosPA.png
  • lazerbeardlazerbeard Registered User regular
    edited May 2009
    There's always gamedev for more serious discussions. The DirectX forum in particular can be pretty helpful, there's a few Microsoft MVPs who seem to monitor that forum pretty regularly. If anyone wants to start an additional programming thread for more advanced topics, I'd lurk on that thread too, though I'd probably be more inclined to post if it was something I was a bit more interested in.

    Sidenote, I would never, ever, ever want to debug someone's threaded code over a forum.

    also
    Obs wrote: »
    now discuss pointers in relation to threading.

    Just a quick note here though, I've only done a bit of work with threading, but in general when reading a pointer which can be modified by another thread, do yourself a favor and assume that the data you are reading will be overwritten by the other thread as you are reading it unless you explicitly prevent it. The easiest way to prevent this is with a semaphore, and critical sections. There are other ways yes, but this is the easiest way.

    When I've done threading in the past, I just cheated, and kept a copy(or partial copy) of the data on each thread, and when I needed to get that data, I put up the semaphore, memcpy()ed from one thread to another, then took down the semaphore, and worked with my own copy of that data.

    lazerbeard on
  • ObsObs __BANNED USERS regular
    edited May 2009
    Infidel wrote: »
    I think it's more that this is a gaming comic forum that we're only covering beginner stuff, we're not really the place to go for more advanced topics.

    And honestly the advanced topics you should be looking at references and courses or something like that, not a thread. This is a pretty good place to come though if you're just a casual person interested in getting into programming, likely due to video games and other computer activities.

    You should, but it doesn't mean you have to. There are forums here for things like art, or writing, or debates, you could even get medical assistance in H/A! Are there better forums for stuff like this? Perhaps. But can these things really be discussed anywhere? Absolutely.

    We're not strictly a "gaming comic forum" not everyone here plays games and not everyone here reads the comics, I pretty much don't read PA comics for months at a time and I haven't really been doing a lot of gaming lately.

    Obs on
  • Smug DucklingSmug Duckling Registered User regular
    edited May 2009
    Anyone can create that thread if they want to. The question is, as questions get deeper and more specialized, will there be anyone here with the necessary expertise to answer the question? Probably in a lot of cases no.

    Smug Duckling on
    smugduckling,pc,days.png
  • InfidelInfidel Heretic Registered User regular
    edited May 2009
    lazerbeard wrote: »
    There's always gamedev for more serious discussions. The DirectX forum in particular can be pretty helpful, there's a few Microsoft MVPs who seem to monitor that forum pretty regularly. If anyone wants to start an additional programming thread for more advanced topics, I'd lurk on that thread too, though I'd probably be more inclined to post if it was something I was a bit more interested in.

    Sidenote, I would never, ever, ever want to debug someone's threaded code over a forum.

    This is all I was meaning by it.

    If you want more in-depth answers, you're better off with already existing places for it. No need to write everything from scratch when you can use a library, right?

    Which also leads to why I think this beginner thread is good, because those other places are not nearly as noob friendly as this thread is. People feel comfortable asking for help on tough problems down to trivial assignment type stuff, and it's all good.

    Infidel on
    OrokosPA.png
  • mastmanmastman Registered User regular
    edited May 2009
    Anyone can create that thread if they want to. The question is, as questions get deeper and more specialized, will there be anyone here with the necessary expertise to answer the question? Probably in a lot of cases no.

    I'd say the odds are pretty good. There is plenty of people on this thread who have been working in the programming profession for years. It's probably just difficult to make sure your question, when it involves language/environment and other such specialized areas, is seen by the right person. The toolset and field is too huge for someone to be feel comfortable in all products/environments/processes/methods etc.

    mastman on
    ByalIX8.png
    B.net: Kusanku
  • ASimPersonASimPerson Cold... and hard.Registered User regular
    edited May 2009
    There already was/is an advanced programming thread and it died a slow death. I don't think there's anything stopping anyone from making a new one, though.

    ASimPerson on
  • LoneIgadzraLoneIgadzra Registered User regular
    edited May 2009
    So, I am trying to figure out how to display and allow the editing of highly relational data from a database server in a WPF DataGrid. It's fun.

    And by "fun" I mean I want to pull my goddamn hair out.

    Edit: Holy shit, I think I finally realized how to do this! Use an object-relational mapper (I'm trying NHibernate at the moment) to load the rows from the database as an array of objects, which is then used as the data source for the DataGrid (rather than a DataTable from a DataSet).

    LoneIgadzra on
  • ObsObs __BANNED USERS regular
    edited May 2009
    o jesus this thread

    mastman wrote: »
    Anyone can create that thread if they want to. The question is, as questions get deeper and more specialized, will there be anyone here with the necessary expertise to answer the question? Probably in a lot of cases no.

    I'd say the odds are pretty good. There is plenty of people on this thread who have been working in the programming profession for years. It's probably just difficult to make sure your question, when it involves language/environment and other such specialized areas, is seen by the right person. The toolset and field is too huge for someone to be feel comfortable in all products/environments/processes/methods etc.

    We specialize. For instance, if someone asked me iPhone or some Cocoa development questions I could probably answer it.

    Obs on
  • LoneIgadzraLoneIgadzra Registered User regular
    edited May 2009
    So, the more I use C++, the more I hate it. It's funny that a language with so much syntax has so many frustrating limitations, necessitating even more syntax to get around them.

    LoneIgadzra on
  • ObsObs __BANNED USERS regular
    edited May 2009
    What syntax do you hate

    Obs on
  • Maxim TomatoMaxim Tomato Registered User regular
    edited May 2009
    I saw someone earlier mention that Perl is a bad language for beginners. Why is this? I ask because I'd like to learn Perl, but I have little programming experience. I started on Java, but I never got very far. Should I just get back into Java for the time being?

    Maxim Tomato on
  • CmdPromptCmdPrompt Registered User regular
    edited May 2009
    I saw someone earlier mention that Perl is a bad language for beginners. Why is this? I ask because I'd like to learn Perl, but I have little programming experience. I started on Java, but I never got very far. Should I just get back into Java for the time being?

    Perl is an absolutely wonderful language, but the syntax can be very confusing for beginners, especially with variables.

    That said, I'm not a huge fan of Java either. Python might be a good idea, as it seems to be the defacto standard for beginners.

    CmdPrompt on
    GxewS.png
  • LoneIgadzraLoneIgadzra Registered User regular
    edited May 2009
    CmdPrompt wrote: »
    I saw someone earlier mention that Perl is a bad language for beginners. Why is this? I ask because I'd like to learn Perl, but I have little programming experience. I started on Java, but I never got very far. Should I just get back into Java for the time being?

    Perl is an absolutely wonderful language, but the syntax can be very confusing for beginners, especially with variables.

    That said, I'm not a huge fan of Java either. Python might be a good idea, as it seems to be the defacto standard for beginners.

    Python is the way to go. Perl's regular expression syntax is both incredibly powerful and incredibly a pain in the ass to remember or read due to over-use of single-letter operators, and it has a lot of weird built-in variables that are hard to remember, though this probably wouldn't be a showstopper for a beginner. Also, I bet file input/output using this thing "<FILE>" would be confusing for a beginner. Those aspects notwithstanding, it works fine for learning about the basics, like control structures and procedures, I would imagine.

    Java is okay, but probably not the best for a beginner due to the enormous libraries and object oriented syntax being in your face from the get-go. Definitely worth coming back to once you have some concept of what object-oriented programming is all about, but a little rough to start in.

    Python, on the other hand, is just a very simple language on the outset. Like any language, it gets very deep, but for learning the basics like functions and control structures it is a good way to go.

    Dare I say, C might be a good choice too, since it is also simple. But it is a little "close to the metal" so you won't be doing fun meaningful things from the outset. But for learning the basics, it's fine as well. And if you stick with it, you will have some awareness of the realities of programming without a managed environment, and begin to see how classes might be useful from a perspective of having to deal without them.

    Bottom line is, it doesn't matter what language you choose, as long as you stick with it. Once you learn one, learning others gets easier and easier.
    Obs wrote: »
    What syntax do you hate

    Out of control template and const correctness syntax for one. Using the STL containers for serious purposes along with shared pointers and every other goddamn thing gets confusing fast.

    Also, initialization lists are pretty much retarded. A whole new syntax just to be able to have almost no control over how my object is initialized. Yay. They are the only way you can call a super-class' constructor too, which is just... words fail me. I don't even use C++ constructors any more, and instead write virtual init methods, especially in a situation where I'm using inheritance a lot.

    LoneIgadzra on
  • lazerbeardlazerbeard Registered User regular
    edited May 2009
    Well, the default constructor always gets called if you don't specify a more specific constructor, but if you need to pass parameters, yeah you need to use MIL. I'll agree with you on templates, you can do some really cool stuff with em, but I usually stay away from them unless I really need 'em. No one said C++ was an easy language, but I like it, cause it gets the job done, fast.

    C is cool too, I'd recommend it to a beginner, as was said before, just don't expect to have anything super impressive in the first month or so.

    lazerbeard on
  • Nova_CNova_C I have the need The need for speedRegistered User regular
    edited May 2009
    Okay, this is driving me nuts. I spent the last I don't know how many years programming in Java and I'd only just started doing OOP in C++ when I switched. Now that I'm back to C++ I'm going insane. :P

    Although I think I finally have pointers and references completely figured out now. Which is good. Because they always gave me fits before.

    Anyway, I'm trying to do OOP in C++ from the ground up this time and I want to keep my classes in separate files. So I have a .h declaring all my functions and variables and a .cpp defining all the functions for each class. After much googling, I figured out that my C++ book was a much better reference and solved the issue of the compiler telling me my stuff was declared more than once (Inclusion Guards!).

    However, the problem I'm having now is that every single function in every single class I have is generating an "error: LNK2005" when linking. Every solution for the error I can find is assuming that the problem is caused by including other libraries when all I'm trying to do is compile my three classes and a main method that uses them.

    What don't I know about classes in C++ that is causing this?

    Nova_C on
  • ecco the dolphinecco the dolphin Registered User regular
    edited May 2009
    Nova_C wrote: »
    Okay, this is driving me nuts. I spent the last I don't know how many years programming in Java and I'd only just started doing OOP in C++ when I switched. Now that I'm back to C++ I'm going insane. :P

    Although I think I finally have pointers and references completely figured out now. Which is good. Because they always gave me fits before.

    Anyway, I'm trying to do OOP in C++ from the ground up this time and I want to keep my classes in separate files. So I have a .h declaring all my functions and variables and a .cpp defining all the functions for each class. After much googling, I figured out that my C++ book was a much better reference and solved the issue of the compiler telling me my stuff was declared more than once (Inclusion Guards!).

    However, the problem I'm having now is that every single function in every single class I have is generating an "error: LNK2005" when linking. Every solution for the error I can find is assuming that the problem is caused by including other libraries when all I'm trying to do is compile my three classes and a main method that uses them.

    What don't I know about classes in C++ that is causing this?

    Sounds like you're using Visual Studio. Are you using the IDE?

    If so, can you make sure that all the .cpp files are added to your current project?

    ecco the dolphin on
    Penny Arcade Developers at PADev.net.
  • Nova_CNova_C I have the need The need for speedRegistered User regular
    edited May 2009
    Visual C++ Express 2008.

    I created them within the project. Do they need to be 'added' to the project even after creating them within?

    Nova_C on
  • Nova_CNova_C I have the need The need for speedRegistered User regular
    edited May 2009
    Oh fuck me.

    ...disregard.....
    I was including a .cpp instead of a .h in one of the class files that was using another class as a member.

    Nova_C on
  • lazerbeardlazerbeard Registered User regular
    edited May 2009
    spoilers will not hide your shame! Seriously though, if you're using the #define/#ifdef codeguard, I've found
    #pragma once
    
    to be easier

    lazerbeard on
  • ASimPersonASimPerson Cold... and hard.Registered User regular
    edited May 2009
    lazerbeard wrote: »
    spoilers will not hide your shame! Seriously though, if you're using the #define/#ifdef codeguard, I've found
    #pragma once
    
    to be easier

    Beware that #pragma once is not standard, and some compilers don't implement it correctly, including GCC before 3.4.

    That said, it's also unlikely you'll run into problems with it. Just sayin', though.

    ASimPerson on
  • FagadabaFagadaba Registered User regular
    edited May 2009
    Thanks a lot for these excellent explanations on pointers! Although I still don't understand why you'd want to use them. For better management of memory?

    [edit] Holy shit I think I got it! When you use the variable it just copies the value. Let's say I have var = 1 and then var = var + 1. var will stay at 1 and uh, no, shit, nevermind.

    Fagadaba on
  • ASimPersonASimPerson Cold... and hard.Registered User regular
    edited May 2009
    Fagadaba wrote: »
    Awesome explanations on pointers guys! Thanks a lot! Though, why would I want to use pointers instead of the actual variable? Like,
    int pipi=3
    printf(%d, &pipi)
    
    ?

    Huh? The code you just wrote would print the address of pipi, unless that's what you wanted.

    Anyway, there are couple of main reasons you need to use pointers.
    1) Consider the case of two functions, foo and bar, defined and called as such:
    void foo (int a);
    void bar (int *b);
    
    void main() {
        int test = 5;
        foo(test);
        bar(&test);
    }
    
    When test is passed to foo(), the value of test is passed to foo. This is known, appropriately, as pass-by-value. What this means is that foo knows that the parameter a has a value of 5. If foo changes the value of a, the value of test back in main() is unaffected. The effectively means the value test is copied to foo(), which sometimes is okay for things like integers, but let's say you've got a 100-byte character array or a big-ass struct allocated somewhere. You usually don't want to pass these things by value because the stack is a finite resource and it's also cumbersome. (If you don't know what the stack is, well, I'll let someone else explain because I'm tired.)

    When test is passed to bar(), the address of is passed to bar. This is known as pass-by-reference, since bar only gets where the value of test is stored in memory, not what the value of test is. For an interesting demonstration of the effect of this, compile and run the following program:
    #include <stdio.h>
    void foo (int a) {
       a = 4;
    }
    void bar (int *b) {
       *b = 6;
    }
    void main() {
        int test = 5;
        printf("Test 1: %d\n", test);
        foo(test);
        printf("Test 2: %d\n", test);
        bar(&test);
        printf("Test 3: %d\n", test);
    }
    

    What values are printed?
    Answer below:
    5, 5, 6. The reason is because since bar() has the address of test contained in the parameter b, deferencing b and assigning it a value changes the value at the address b points to. This is one of, if not the, most important pointer concepts and is why they exist.

    Also, when you memory allocation you'll realize why allocating everything on the stack isn't all that great, and to use other allocators you have to use pointers.

    Hopefully this made sense, and if not, someone less tired than me can probably do it better. :)

    ASimPerson on
  • bowenbowen How you doin'? Registered User regular
    edited May 2009
    Why exactly does obs want to know about threading and pointers?

    Threading, pah!

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • iTunesIsEviliTunesIsEvil Cornfield? Cornfield.Registered User regular
    edited May 2009
    Ig-no-rance: does threading make pointers/references more difficult to use? I (luckily) rarely leave Magical Managed Land, so I do not often deal with unmanaged code.

    Is the difficulty about race-conditions, or is there some other sweet hell that some of you guys have to deal with?

    iTunesIsEvil on
  • ObsObs __BANNED USERS regular
    edited May 2009
    bowen wrote: »
    Why exactly does obs want to know about threading and pointers?

    Threading, pah!

    I don't, but others do.


    Threading is going to be very important anyways in the upcoming years as there is an increasing emphasis on packing in more cores into processors rather than just having single core powerful processors. If you are strong in parallelization you are ahead of the game

    Fortunately for Mac programmers, the upcoming Grand Central in OS X 1.6 will make parallelism easy as hell, you pretty much won't need to be an expert in threading at all to make applications with heavy parallel processing. OpenCL is also coming out in the next OSX, which will allow processing to occur on video cards. So basically instead of being limited to only 4 cores on the CPU you can also use the 240 cores found in some graphics cards. All new Macs have Nvidia graphics cards.

    Obs on
  • ObsObs __BANNED USERS regular
    edited May 2009
    Also, you can also use functional programming to build highly parallel apps without worrying about variables getting fucked up or anything but functional programs are a lot harder to write.

    Obs on
  • bowenbowen How you doin'? Registered User regular
    edited May 2009
    Ig-no-rance: does threading make pointers/references more difficult to use? I (luckily) rarely leave Magical Managed Land, so I do not often deal with unmanaged code.

    Is the difficulty about race-conditions, or is there some other sweet hell that some of you guys have to deal with?

    Race conditions and dealing with mutexes is the largest load of crap in craptown. Most people use a lock system and that's just not acceptable. I mean there are datatypes that are thread friendly for the most part and excluding some awkward race condition you can get away with it.

    Are pointers hard to use with a thread? No, they function the same, you use them the same, you just have to make sure you're not reading while someone else is writing.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • InfidelInfidel Heretic Registered User regular
    edited May 2009
    Pointers are super handy in things like data structures. You use them every time you work with a linked-list or a tree or such.

    And not just in C, you're using them in Java when you implement those. You just don't know it! :P Object variables? Pointers!

    Infidel on
    OrokosPA.png
  • bowenbowen How you doin'? Registered User regular
    edited May 2009
    I hate managed code with a passion for some reason. It's so... lazy and doesn't let me do cool things.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • MagicPrimeMagicPrime FiresideWizard Registered User regular
    edited May 2009
    I am creating a web-page that has a series of include files assigned to hover-over pop ups done in CSS.

    When you hover over a title, the list expands having more information about whatever list entry is highlighted.

    The include file links are done in php. Is there a script that can create a link that when clicked will only print the include file?

    MagicPrime on
    BNet • magicprime#1430 | PSN/Steam • MagicPrime | Origin • FireSideWizard
    Critical Failures - Havenhold CampaignAugust St. Cloud (Human Ranger)
  • InfidelInfidel Heretic Registered User regular
    edited May 2009
    MagicPrime wrote: »
    Is there a script that can create a link that when clicked will only print the include file?

    I uhh, am not sure what you mean by all this. Could you clarify?

    Infidel on
    OrokosPA.png
  • bowenbowen How you doin'? Registered User regular
    edited May 2009
    You know what's an awesomely overlooked tool that doesn't get used much anymore? Bitmasking and Bitwise operations.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
This discussion has been closed.