How do fortran 77 programmers manage without dynamic memory allocation? - fortran

I'm starting to learn Fortran, coming from a C++/Matlab/Java background. I realize that some Fortran programmers are still clinging to F77, maybe because they don't like object orientation, namespaces and stuff, and are used to the old syntax.
I understand that you can write a program without OOP. What I don't understand is how you can do without dynamic memory management. There are a thousand examples of cases where you don't know the array sizes in advance - for instance when converting a full matrix to a sparse one.
Of course, modern Fortran offers both "automatic arrays" and "allocatable arrays". But these were not present in 1977. How do the F77 guys manage without these constructs?

Within the standard language, the approach was typically to set aside storage in an array that was larger than likely needed, but still within the constraints of the platform running the program, then manually parcel that storage out as required. The language had features, such as sequence association, storage association, and adjustable arrays, that helped with this parcelling.
Use of language extensions for dynamic memory management was also common.
The capabilities of Fortran 77 and earlier need to be considered in the context of the capabilities of the platforms of the time.

Related

Are arrays primitives in C++?

I thought the term primitive was used for data types in C++, but when I search up on Google if arrays are primitives in C++, the first popular result says arrays are primitives in C++. I know arrays are built in C++, but I have never heard the term of primitive being used for array in C++. Is the term primitive able to be used on data structures as well, instead of just data types? How are arrays primitives sin C++.
Here is the link: http://icarus.cs.weber.edu/~dab/cs1410/textbook/7.Arrays/cpp_v_java.html
C++ at its core is base language which allows for creating integral types, pointers, static arrays, classes, enums, etc. You can create static vectors such as char array[32], but these obviously cannot be resized easily and make bugs more prone. It's essentially C with a whole ton of extra language features. (side note: don't be fooled, they are different languages. You can easily tell when someone has written C++ code, when they are a C or Java programmer).
C++ is actually a standard, which means multiple organisation will implement the C++ standard in their own way. C++ does not want and should not be responsible for implementing every language feature that every user wants, as this makes the standard bloated and too hard to maintain for all vendors. There are too many people using the language for too many different, specialised things that it's not possible to make everyone happy.
What C++ has done though, is to create general-purpose libraries on-top of the base C++ language which makes things such as dynamic-arrays (vectors), managed pointers(shared_pointers), and other common features available to the user. This library is known as the STL, and for most users, is used in almost every piece of code they write. Reference: https://en.cppreference.com/w/ for more information on the STL. To answer your confusion, these are almost primitive types due to always being used, but strictly speaking, primitive types are only built into the language.
If someone is coding for a high-performance game, then they may not use the STL as it could be too slow. They may use a completely different library which is faster. Smaller size on disk or anything else they desire. That's the beauty of C++ - you can pick and choose anything you want, so C++ works for you, not against you, no matter the industry you are in and no matter what your needs are.
As a foot note: To add more confusion to the mix, C++, like many other languages has been evolving. The version of C++ you are using is the year number, ie: C++03, C++11, C++14, C++17, C++20, etc etc. Each one of these versions added more features to both the base c++ language and to the STL. So when coding, make sure the compiler you are using supports the features you want. I'd suggest C++11 at a bare minimum these days.
Sort of. C++ has built-in C-style arrays, which are problematic for many reasons, including that they don’t have a known size, they decay to a pointer, etc. So yes, C++ has built-in arrays in the language. Furthermore, the C++ standard library has several array-like containers. Typically you want to use these: we are writing C++ not C after all. So if you want a fixed-size array (size known at compile time) consider std::array of you don’t know the size up front, choose std::vector.

why c++ allows pointers if they can generate problems like accessing private members?

I have read about c++ pointers and their pitfalls, one of which is that one can access private data members of other class objects using pointer hacks as mentioned here and here.
Surely pointers in c++ gives a lot of flexibility to the language but what's the use of it if it can hamper the core OOP features of the language like data hiding ? Is this really a trade-off between security & flexibility ?
C++ is first and foremost a low level language that extends traditional C with fancier language constructs. With few exceptions, nothing was removed.
C++ is not just an OO language. It is functional, declarative, procedural, structural amd object oriented. It can even be used as a portable assembler, like C often is.
Pointers are a thin abstraction on top of how CPUs access memory. Having access to raw pointers in-language enables a huge amount of efficient code. Every systems programming language permits access to raw pointers; sometimes guarded by "unsafe" blocks; and C++ is also a systems programming language.
If you are coming at C++ from a single perspective, and wondering why it seems strangely shaped for your goals, try looking at it from another direction.
C++ was originally built on the C language. It added features without removing any. C had pointers and therefore C++ has pointers. Compatibility with the C interface remains an essential feature of C++. Therefore pointers will never be not-allowed.
Besides compatibility, pointers are very useful. Introducing object oriented programming to a system programming language being the initial reason for C++, it should be noted that indirection is essential for implementing runtime polymorphism. Sure, there is another method of indirection in C++ - references, but references are more limited and cannot be used to implement all algorithms that require the use of pointers.
Pointers are also required to implement node based data structures such as trees or linked lists.
c++ pointers and their pitfalls, one of which is that one can access private data members of other class objects using pointer hacks as mentioned here
That trick isnt so much enabled by the pointer but by the use of reinterpret_cast. It would be much more sensible to question why that language feature is allowed.
and here
Both this and the previous are cases where the language does not allow breaking of encapsulation. The problem isn't the pointer. The problem is that C++ - like C - has undefined behaviour (UB) when certain rules are violated.
You might be wondering, why does a language have UB. The answer is that if the rules were required to be checked at runtime to avoid UB, the program would necessarily be slower than it could be when we assume that the program didn't make a mistake. Since C and C++ are low level system programming languages, performance was chosen at the cost of protecting against bad programmers.
There is no trade-off involving security. That's because there is nothing to trade, since C++ does not offer security. The language offers tools (like data hiding) and compilers offer guardrails (most warnings) to help you do the right thing, but if you are determined to do the wrong thing in your program, you have the freedom to do so. Vive la résistance! Watch program crash override and acid burn.
Besides, if you want to access private members, there is a much simpler method that does not involve undefined behavior: edit the header files, and either change "private" to "public" or add your class/function as a friend. (I'm not sure if this affects ABI. You might need to recompile libraries. I did say "simpler" not "quicker".) No pointers involved.

Microcontrollers using C or C++ [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there any reason to use C instead of C++ for embedded development?
I'm very curious about this: Why is it that when we deal with microcontrollers, they prefer C instead of C++? Based on my researches, C and Assembly language is the usual programming language for these devices. I only know C++ and Assembly Language. So in this case, should I start learning C or stick with Assembly language and if so, what compiler should I use because I only know the Turbo Assembler.
Thanks and more power! :)
Some C++ features like exceptions and virtual functions can add overhead to your program which is undesirable in highly resource constrained environments. This reduces the demand for C++ compilers on such platforms. It is also much more difficult to implement a C++ compiler than a C compiler. This difficulty plus lack of demand makes it so many micro-controllers only have C compilers available for them.
I would learn C for your micro-controller programming. It is not difficult to learn C after learning C++ and will be much easier to code in than assembly.
It is merely historical accident and practice (by old-time Luddites like me) that ucontrollers "prefer" ASM and C. If your compiler can compile C++ into ucontroller code, there's no theoretical reason that I know of why you should not use C++.
To me, it's much easier and more natural to use ASM and C but you can use whichever you prefer so long as your compiler (and linker, if you use it) can do the right thing; and your ucontroller has enough memory to accomodate the (perhaps bigger) compiled C++ code.
It's just the availability of resources, really, as explained by the other posters. By the time you've compiled in a couple virtual method tables and a couple dozen object pointers, that's all the RAM gone from a simple uC!
That said, I prefer C++ on today's 32-bit controllers with 8K upwards of RAM, plenty of flash, complex embedded peripherals and multitasking libs. After decades of OO, using plain C is nightmarish for anything non-trivial.
I currently use NXP ARM chips & Rowley Crossworks, (IDE, uses gcc). I only use C for lib interfaces and assembler for some drivers, all the rest is C++.
C is more low-level and does just exactly what you say. It is more adapted to low-resources environments such as micro-controllers.
C++ has some features which requires additional resources (such as OOP, exception, and so on).
Moreover the micro-controller does not have the same features as your computer's CPU. It could for example not support dynamic library loading and even for static libraries you're limited in size as your chip doesn't have many memory.
Usually, micro-controllers expose special input/output library, and the stdlib is not always available.
What you need is a cross-compiler for your micro-controller specifically.
Then you can write your program in C and ASM.
If the chip supports it, you can re-compile the stdlib to use the standard C features, and then you can eventually (once again if the chip has enough resources) build a C++ cross-compiler and then the STL. Then you will be able to build C++ program on your chip, but the program will weight much more than the original C program.
Microcontrollers are memory and bandwidth constrained processing units. C programming language generates tight code that is close to assembly language in terms of size and speed. C++ usually carries an overhead in memory and speed.
Another issue is dynamic memory allocation. Using object oriented design with C++ usually implies dynamically creating and destroying objects. Embedded applications using microcontrollers, typically allocate all the required memory statically and is not freed up for the life time of the application.
That being said, if you are using a 32 bit microcontroller and your application is complex enough that it handles either lot of data traffic or has significant user interface via touch screen / LCD etc., C++ (& sometimes even C# ) is the language of choice.
The compiler that you choose would depend on the microcontroller, check the microcontroller vendor website for the appropriate development tool suite to use.
Assembly language is used only for the lowest layers if it cannot be done in C. It is harder to maintain and port assembly language code, hence it is best to minimize its use in your application.
Microcontrollers are small devices which are not very powerfull compared to computers. They have limited resources. Firstly, the size of the stack is very limited, thus it is not recommanded to have many nested function calls (on some devices, the stack is limited to a few bytes). Secondly, it is often not possible to dynamically allocate memory (alloc, free...), and most of the program data must be global static variables or stored in the stack, so usefull classes such as std::vector would not be available.
Even if C++ compilers could be used for microcontrollers, it would not be very useful since the low capabilities of these devices would forbid plain usage of this powerful language. Using C is often easier for simple tasks, and microcontrollers are sized for simple tasks.

To write a bootloader in C or C++?

I am writing a program, more specifically a bootloader, for an embedded system. I am going to use a C library to interact with some of the hardware components and I have the choice of writing it either in C or C++. Is there any reason I should choose one over the other? I do not need the object oriented features of C++ but it does have a stronger type system. Could it have other language features that would make the program more robust? I know some people avoid C++ because it can (but not always) generate large firmware images.
This isn't a particularly straightforward question to answer. It depends on a number of factors including:
How you prefer to layout your code.
Whether there's a C++ compiler available for your target (and any other targets you may wish to use the bootloader on).
How critical the code size is for your application (we're talking about 10% extra maybe, not MB as suggested by another answer).
Personally, I really like classes as a way of laying out my code. Even when writing C code, I'll tend to keep everything in modular files with file-scope static functions "simulating" member functions and (a few) file-scope static variables to "simulate" member variables. Having said that, most of my existing embedded projects (all of which are relatively small scale, up to a maximum of 128kB flash including bootloader, but usually less) have tended to be written in C. Now that I have a C++ compiler though, I'm certainly considering moving to C++.
There are considerable benefits to C++ from simply using references, overloading and templates, even if you don't go as far as classes. Certainly, I'd stop short of using a lot of more advanced features, including the use of dynamic memory allocation (new). Then again, I'd avoid dynamic memory allocation (malloc etc) in embedded C as well if possible.
If you have a C++ compiler (even if it's only g++), it is worth running your code through it just for the additional type checking so that you can reduce the number of problems in your code. The C++ compiler can pick up on a few things that even static analysis tools won't spot.
For a good discussion on many invalid reasons people reject C++, see Dan Saks' article on Embedded.com.
For a boot-loader the obvious choice is C, especially on an embedded system. The generated code will need to be close to the metal, and very easy to debug, likely by dropping into assembly, which quickly becomes difficult without care in C++. Also C tool-chains are far more ubiquitous than C++ tool-chains, allowing your boot-loader to be used on more platforms. Lastly, generated binaries are typically smaller, and use less memory when written C style.
If you don't need to use Object Orientation, use C. Simple choice there. Its simpler and easier, whilst accomplishing the same task.
Some die hards will disagree, but OO is what makes C++ > C, and vice versa in a lot of circumstances.
I would use C unless there is a specific reason to use C++. For a Bootloader you are not really going to need OO.
Use the simplest tool that will accomplish the job.
Write programs in C is not the same as writing it in C++. If you know how to do it only in C++, then your choice is C++. For writing bootloader it will be better to minimize code, so you probably will have to disable standard C++ library. If you know how to write in C then you should use C — it is more common choice for such kind of tasks.
Most of the previous answers assume that your bootloader is small and simple which is typically the case; however, if it becomes more complex (i.e. you need to be able to load from an Ethernet port, a USB port, or a serial port...you need to validate the code that is being loaded before you wipe out your existing code, etc.) you may want to consider C++.
I have also found that the bootloader and the application typically share some amount of common code so you may also want to consider using the same language as your application to facilitate the code sharing.
The C language is substantially easier to parse than C++. This means a program that is both valid C and valid C++ will compile faster as a C program. Probably not a major concern, but it is just another reason why C++ is probably overkill.
Go with C++ and objchoose what language features you need. You still have full control of the output object code as long as you understand the C++ abstractions that you're using.
Use of OO can still run well if you avoid the use of virtual functions. Avoid immutable object types that require a lot of copying in order to pass values, like std::string. But, you can still use features like templates without any real impact on runtime performance.
Use C with µClibc. It will make your code simpler and reduce its footprint. Can be found in: www.uclibc.org.

Abstract Data Types in Fortran 77 (Fortran-II)?

I'm attempting to work in Fotran 77, and I've found the need for a tree based data structure. Aside from implementing a tree with an array, is there any way to build a tree with pointer nodes to other nodes, as per a standard implementation in most languages?
The documentation for this beast is scarce, and there doesn't appear to be any standard structure type that would make this possible.
Thoughts?
I suggest you move to Fortran 90 or later. FORTRAN77 and earlier didn't have pointers in the language specification, so compiler writers (and users) came up with a whole raft of clever* ways of adding the necessary functionality to do just the sort of thing you want to do. Fortran 90 has proper pointers for dynamic data structures.
clever* means, of course requiring advanced programming skills and understanding of memory, pointers, referencing and de-referencing (all of which are alien to most Fortran programmers) with the inevitable consequence that clever* programs are not portable between compilers, nor between hardware platforms, nor between programmers.
I don't understand why you would be restricted to working in FORTRAN77 -- standard FORTRAN77 remains syntactically correct and compilable with Fortran 90 compilers. Sure, you have to integrate your new tree-processing code with the existing codebase in the old language, but that doesn't mean that you have to write new units in the old language.
And, in passing, FORTRAN77 was way more modern than FORTRANII.
This would be much easier in Fortran 95/2003, which has user-defined derived types and pointer types. Using these features one can setup data structures such as linked lists and trees. (The pointer types are called pointers, but they are more like alias, in that pointer arithmetic isn't possible). Fortran >=95 has many improvements over Fortran 77. My recommendation is not to use Fortran 77 unless one is making minor modifications to legacy code that is in Fortran 77. A good book is "Fortran 95/2003 explained" by Metcalf, Reid and Cohen.
If you're really stuck with Fortran-77, you can use Cray Pointers:
http://gcc.gnu.org/onlinedocs/gfortran/Cray-pointers.html
Cray Pointers are non-standard and have some drawbacks, but they'll give you something similar to a C pointer. They're supported by gfortran and most commercial compilers.
With that said, you would probably be better off using newer Fortran features, like Fortran-90 pointers or the C-interoperability features in Fortran 2003.
Without Cray pointers or other hackery, the only way to implement a "data type" is with parallel arrays, each of which represents a field. An index, then, can refer to an instantiation of the data type.