- Discuss: CodeWarrior Development Studio for Mac OS (Mac OS X, Classic Mac OS and Targets) (v. 9) - box pack - 1 user Sign in to comment. Be respectful, keep it civil and stay on topic.
- Aug 04, 1997 CodeWarrior will soon support the Mac OS 8 Appearance Manager by creating new classes in PowerPlant for using the new interface controls, which include sliders, progress bars, group boxes, pop-up menu buttons, bevel buttons, and image wells. Existing PowerPlant grayscale classes are.
- CodeWarrior embedded software development studio is a complete integrated development environment (IDE) that provides a highly visual and automated framework to accelerate development of the most complex embedded applications.
CodeWarrior Downloads Note: many of these files are quite large. We strongly recommend broadband access to successfully download the image. When you run the installer, the tools should install with all features available for 30 days.TechInfo.The process is composed of two major steps:Porting to CodeWarrior is by far the biggest job. If porting toCodeWarrior takes more work than PowerPC specific changes it may notseem worth it to undertake the effort. However, porting to CodeWarriorrequires you to clean up your C code and bring it up to the ANSIstandard. CodeWarrior is a stricter compiler than MPW. Hence portingto CodeWarrior is an important process because making the code ANSIstandard is one of the requirements for porting to the PowerPC. Makingyour code stricter will ensure that it behaves as expected and willavoid possible bugs.
CodeWarrior comes with the Universal Header files from Apple. This is a new set ofheader files that provide access to the toolbox in a way that iscompatible with both the 68K and PPC. Converting your program to usethe Universal Header files is another step that CodeWarrior makes you dothat is ultimately necessary to port your program to the PowerMacintosh.
Porting to CodeWarriorModifying your code to compile with CodeWarrior 68K requires many of thechanges needed to compile with CodeWarrior PPC. The changes can bebroken down into several type:
ANSI ComplianceThe first changes to make to your code are to make it ANSI compliant.MPW is much more lax about what it allows than CodeWarrior is. You cantell CodeWarrior to give you many types of warnings. If your code isold or was compiled with MPW you may need to add function prototypes. Isuggest turning on the 'Require Function Prototypes' option in the'Language' section of the preferences. This will require that everyfunction has a prototype. Here is an example of a correct functionprototype:
int mk_ticket(KTEXT ktext, char *server_name);
There are a few features to note about this prototype. First itexplicity returns
int. Always declare the returntype. Do not assume that if you don't then the procedure will return
int. Many of the procedures in TechInfo that didn't havean explicitly returned type didn't return anything. CodeWarriorcomplained because they were supposed to return
ints butdidn't return anything. This was a warning that MPW didn't catch. Ichanged these to return
void. For example, I changed thisprototype (and the corresponding function call:
Access all of your Google Drive content directly from your Mac or PC, without using up disk space. Download Backup and Sync for Mac Download Backup and Sync for Windows. Google Drive Terms of. Google drive sync mac catalina. Get 15 GB of free cloud storage today and keep your life connected by downloading Backup and Sync from Google for your Mac or PC computer.
This prevents statements such as the following (imaginary) one:
result = cmd_open_document();
The other important feature of the prototype is that it uses new-styleargument declarations. By putting
KTEXT ktext and
char *server_name in the argument list, the compiler cando better type checking and register allocation. It may even uncovererrors.
Prototyping all of your functions may cause additional complications.The first argument to
mk_ticket is of type
KTEXT, which is defined in krb.h. Consequently krb.h mustbe
#included before the function prototype. In TechInfoall of the prototypes are in one header, prototype.h. krb.h must be
#included before prototype.h or inside of it. This mayuncover other conflicts between newly
#included headers orheaders and source files.
Besides declaring all of your functions before using them, removeillegal code. CodeWarrior will catch this code. An example ofcode that CodeWarrior disagrees with is:
(long)select_node = GetWRefCon(window);
An expression with a cast is not an lvalue. However all assignmentexpressions require an lvalue as the left operand. This expressioncan be fixed by type casting the result of
select_node's type. The proper expression is:
select_node = (Handle)GetWRefCon(window);
Another problem that might occur when you move to CodeWarrior isredefined macros. MPW prior to version 3.3 allowed macros to beredefined. Version 3.3 allows macros to be redefined if they arebeing redefined to the same thing. CodeWarrior doesn't allow macrosto be redefined.
FALSE are oftendefined. I wrapped these in
#ifndef's to preventredefinition.
It's quite possible you will encounter other irregularities in thecode you are porting. There are some subtle implementationdifferences between MPW and CodeWarrior.
MPW swaps the ASCII value of 'r' and 'n'. It does this because theMac uses 'r' to break lines but 'n' is commonly used for new lines instandard C library routines such as
printf. CodeWarrior'sANSI libraries translate 'n' as far as I can tell. You could swap allof your 'n's to 'r' but then your code wouldn't work after beingcompiled by MPW. There are two solutions to this problem. One is toturn on 'MPW Newlines' in the 'Languages' section of the preferences.The other is to
#define macros, such as
LF with the ASCII values of 'n' and 'r'. Inside ofstrings use the octal value (e.g. 'foo012').
Another implementation difference is the size of
int. InMPW and CodeWarrior PPC
int is 4 bytes. In CodeWarrior 68Kit is 2 bytes unless you tell CodeWarrior 68K to use 4 byte
ints in the 'Processor' section of the preferences. Makesure you tell CodeWarrior that
ints are 4 bytes if youdepend on this. Ideally you should only use
ints when youdon't care how big
int is and
short when you do.
Universal HeadersThe Universal Headers require some changes to your code. The changescan be broken down into three major parts:
Obsolete Toolbox CallsSeveral toolbox calls are obsolete. If you try to compile your programand a prototype is lacking for a toolbox call, it's quite possible thatthe call is now obsolete. TechInfo used to use
GetAppParmsto get its name and resource reference number. I had to replace thiscall with a call to get the low memory global that contains theapplication's name and a call to
CurResFile. The call to
CurResFilehas to be made at the beginning of the programwhile the application is still the current resource file. Otherobsolete calls are
GetAppFiles. These calls are needed for System 6applications but they are obsolete on the PowerPC. To maintain a commoncode base it is a good idea to remove these from the 68K code. If youreally want to use obsolete calls you need to
#define OBSOLETE1. It is
#defined as 1 if you are using CodeWarrior68K, so obsolete calls won't be caught until you try to compile for thePPC unless you modify MacHeaders.c in the MacHeaders directory. There'sa line in that file that defines
OBSOLETEto be 1 if thecompiler is not a PPC compiler. Comment this line out and re-precompileMacHeaders68K to have the obsolete calls caught by the 68K compiler.Other obsolete calls are
Low Memory GlobalsYou should not access low memory globals directly on the Power Mac. ThePower Mac architecture is different from the 680x0 architecture so thereis no guarantee that the low memory globals will even exist. Apple hasremoved the SysEqu.h header file, which contained the names of theglobals, and replaced it with LowMem.h. LowMem.h contains accessor andsetter functions for the low memory globals. For example, TechInfo usedthe
WindowListlow memory global but was modified tocall
LMGetWindowList(). If you use low memoryglobals the compiler will generate errors, first because SysEqu.h can'tbe found, and, once you remove the
#includefor it, becauseit won't recognize the globals. You'll need to
#includeLowMem.h and replace the globals with
Universal Procedure PointersThe biggest change you will need to make are to ProcPtrs, the procedurepointers that are passed to toolbox calls. For instance, TechInfo calls
ModalFilterProcPtr. Ifyour program is running on a Power Mac,
ModalDialogdoesnot know if the filter procedure is 68K code or PPC code because thePower Mac can execute both. Consequently you cannot simply pass yourprocedure's pointer because you have to indicate what kind ofinstruction set it was compiled for. Apple has created a structurecalled
RoutineDescriptorwhich describes the callingconvention for a procedure and also the CPU it was compiled for. Apointer to a routine descriptor is called a Universal Procedure Pointer(UPP). Instead of passing a pointer to your callback routine, you needto pass a UPP. If you are compiling for the 68K a UPP is simply aProcPtr. If you are compiling for the PPC it is a pointer to a routinedescriptor. You do not have to worry about which it will be because thatis abstracted away using macros. Always use UPPs and the compiler willdo the right thing.
There are several ways to create routine descriptors. A routinedescriptor requires about 32 bytes of nonrelocatable memory. If youallocate it in the heap during runtime you might fragment memory. Oneway to avoid this is to allocate your routine descriptors on the stackas global variables. There is a macro in MixedMode.h that willaccomplish this. TechInfo has a procedure called
dlog_login that prompts a provider for his/her username andpassword. It wants to pass the procedure
ModalDialog wants a UPP, in thiscase a UPP of type
ModalDialogUPP. Here's how to createthe routine descriptor on the stack:
RoutineDescriptor gGetIdFilterRD = BUILD_ROUTINE_DESCRIPTOR(uppModalDialogProcInfo, GetIdFilter);
BUILD_ROUTINE_DESCRIPTOR is simply a macro that expands into a
The other way to create a routine descriptor is dynamically on theheap. You should allocate your routine descriptors at applicationstartup because they are not relocatable. Apple has provided aroutine,
NewRoutineDescriptor, that takes a procedure,procedure calling information, and the CPU type the procedure wascompiled for. This routine returns a UniversalProcPtr,which is a pointer to a routine descriptor. The Universal Headerscontain many macros to create specific UPPs. Instead of calling
NewRoutineDescriptor, here is how TechInfo creates a UPPfor
gGetIdFilterUPP = NewModalFilterProc(GetIdFilter);
The macro calls
NewRoutineDescriptor with the correctcalling convention and CPU specified. You can look in the appropriateheader to find the macro that will create the kind of UPP that youneed. Notice that the UPP is a global variable. TechInfo has afunction in main.c called
InitRoutineDescriptors that iscalled at startup.
InitRoutineDescriptors calls routinesin other files, such as dialogMgr.c, that create UPPs for the routinesin the respective files. The routine in dialogMgr.c,
gGetIdFilterUPP asshown above, so
gGetIdFilterUPP needs to be global sothat it can be used in
Now that the
RoutineDescriptor has been created it can bepassed to
ModalDialog in place of the
ModalFilterProcPtr. Here is how to use the
If you created a UPP, here is how to use it:
Sometimes you might not be able to create allocate a UPP dynamically atapplication startup. For example, when I ported the BSD library, therewas no routine that I could count on being called at application startuptime so I allocated the UPP local to the procedure that needed it.After I was done with it I disposed of it using the function
DisposeRoutineDescriptor, which takes a UPP as itsargument:
Codewarrior Download Mac
You have to be careful not to dispose of a UPP prematurely, for exampleif you pass it to an asynchronous routine.
You cannot directly call a UniversalProcPtr like you would a ProcPtrbecause a UniversalProcPtr is not actually a pointer to a procedure.You won't usually need to call a UPP yourself since they are mostly usedas callback routines, but there are times when you might. TechInfoneeds to call one in
PascalClikLoop, which is used byTextEdit. The reason why will be covered in the PowerPC section.
CallUniversalProc in the Mixed Mode Manager handles modeswitches and executes the routine associated with the UPP.
CallUniversalProc takes the UPP, information about thecalling convention for the procedure, and the arguments to theprocedure. As in the case of
NewRoutineDescriptor thereare macros in the Universal Headers for each specific kind of UPP.TechInfo directly calls the
TEClickLoop hook with theline
When you compile a program that doesn't use the Universal Headers inCodeWarrior, CodeWarrior will catch most of the callback routines thatneed to be replaced with UniversalProcPtrs. One case thatwill not be caught is when you try to put a userItem into a dialog boxusing
SetDItem. This case will not be caught because youhave to typedef the ProcPtr for the userItem to a handle. You stillneed to pass a UniversalProcPtr instead of a ProcPtr.
CodeWarrior SpecificsCodeWarrior handles these topics differently than MPW:
Precompiled HeadersOne reason MPW is so slow is that it has to compile thousands oflines of header files. CodeWarrior doesn't have to do this because itsupports precompiled headers. The existence of the MacHeaders68K andMacHeadersPPC files is one of the reasons why CodeWarrior issignificantly faster than MPW. MacHeaders* contains many of thecommonly used headers so you will no longer need to
#includethe header files that are covered by MacHeaders*.You may still wish to if you are not using CodeWarrior, for instance ifyou want the code to compile in CodeWarrior and MPW. In this case youshould
#includelines out. Theconstant
__MWERKS__is defined in the CodeWarriorenvironment. You can either
#includeMacHeaders* in yourcode or set it as the 'Prefix File' in the 'Language' section of thepreferences.
In the case of TechInfo I wanted to precompile other headers besidesthe universal ones. Many of TechInfo's source files
#include standard C headers. TechInfo also has its ownlarge headers files that need to be
#included by everysource file. One difference between MPW and CodeWarrior is that MPWallows constants to be
#defined on the command line. MPWalso
#defines constants that aren't
#definedby CodeWarrior. To deal with this, I created a header for TechInfo,TI.includes.pch, that
#includes MacHeaders, and
#includes otherheader files. This file is precompiled, and the result, TIFast*, is setto the Prefix File.
It is inconvenient to precompile TI.includes.pch every time I change oneof the files that it depends on. CodeWarrior will automaticallyre-precompile any header that ends in .pch if it is added to the projectfile. The same .pch file can be used to generate 68K and PPC version ofthe precompiled header. TI.includes.pch has these lines in it for thatpurpose:
Toolbox GlueMPW has C glue code to ease the use of C strings with toolbox routines,which expect pascal strings. For example, MPW supports the
numtostringroutine, which is just like
NumToStringexcept that it takes a C string. CodeWarriorlacks this routine and a couple others of the same breed, so you willneed to rewrite them if they don't already exist.
Assembly CodeMPW has an assembler that takes care of .asm files. The ClickLooppassed to TextEdit is traditionally written in assembly. The procedureusually saves registers, calls the TextEdit's default ClickLoop, callsthe program's real ClickLoop, restores the registers, and puts a 1 inregister D0. CodeWarrior doesn't assemble .asm files, but it willassemble
asmprocedures in C source files. Here isTechInfo's
AsmClikLoop, which is in textMgr.c:You only want to assemble this code if you are using CodeWarrior becauseMPW will not understand it. Since this is 68K code, you don't want itassembled by the PowerPC compiler. In fact, CodeWarrior does notcurrently support PPC assembly.
Code ResourcesYou need to create a new project for each code resource. CodeWarriorcan handle multisegment resources but I won't go into that becauseTechInfo doesn't use them. In the preference section 'Project' set theProject Type to 'Code Resource'. Then give the file to put the coderesource into, the type of code resource, and its resource ID. You canhave CodeWarrior prompt you for the location to save the resource byselecting the 'Display Dialog' check box. If you select the 'Merge ToFile' check box the code resource will be added to the file instead ofreplacing it. TechInfo merges all of its code resources into one file.Make sure the Code Model in the 'Processor' preferences is set to'Small.' A code resource cannot use the large model. If you cannot fitthe code resource into the small model you will need to create amultisegment one.
Unlike MPW, you cannot specify the entrance procedure to the coderesource. You have to name it
Application ResourcesThe usual way to create resources for an application being created byMPW is to specify them in a .r file and run Rez on the .r file to createand merge the resource into the application. I create and modifyresources using ResEdit, so I have to DeRez my changes and add them tothe .r file. It is easier to skip the DeRez step and just merge theresources created or modified by ResEdit into the application.
It is much easier to use resource files in CodeWarrior than it is to use.r files for the reason stated above and because CodeWarrior does notautomatically run Rez on .r files. You can simply add a file withresources in it to your project, and the resources will be added to yourapplication when it is built. If you wanted to store your resources in.r files, you would have to use ToolServer, which CodeWarrior cancontrol, to run Rez. If you choose to use a resource file and not useRez, you will still need a .r file for MPW. Instead of having a .r filethat duplicates the resource file, you can create a very simple .r filethat will include the resource file.
Power Macintosh Specific ChangesIf you have ported your application to CodeWarrior as described above,being sure to use UPPs, then you've done most of the work required toport an application to the PowerPC. There is very little differencebetween writing a 68K and a PPC program. When writing a PPC program,the biggest problem to worry about is mixed mode switches and that you don't pass PPC code to a procedure expecting68K code or vice versa. This section will discuss these issues that youshould be aware of when porting your CodeWarrior 68K program toCodeWarrior PPC:
Creating a CodeWarrior PPC ProjectOnce you have a 68K project, you probably don't want to recreate a PPCproject. CodeWarrior PPC can open CodeWarrior 68K projects files, soyou don't have to recreate it. Once you open your 68K project inCodeWarrior PPC, you still have to make some changes. First of all, the68K and PPC projects need different libraries to interface the Macintoshtoolbox. You will need to remove the 68K libraries from the project andreplace them with PPC versions. Instead of MacOS.lib, the PPC projectneeds MWCRuntime.Lib, InterfaceLib, and MathLib.
Codewarrior Mac Os 9
You also need to change some of the preferences. You can set a numberof PPC specific preferences in the 'Processor' panel. The PowerPC likesto have data stored on natural boundaries. A
char canstart at any address. A
short should start at an evenaddress, and a
long should start at an address that is aneven multiple of 4. While this is not necessary it makes memory accessfaster. You can set structures to use this alignment in the 'StructAlignment' popup menu. If you do, be careful not to pass a PPC alignedstruct to a toolbox call. Toolbox calls were written for the 68K andexpect structures aligned for that processor. You don't need to worryabout structures from the Universal Headers; those are alignedcorrectly. If you pass your own you should enclose the structuredefinition in
#pragma options align=mac68k and
#pragma options align=reset. The other options in the'Processor' panel let you set the level of optimization.
That is about all there is to porting to the Power Mac unless you have68K assembly code in your program.
Assembly CodeCodeWarrior 5 doesn't have a PPC assembler. Apple says that youshouldn't need to write any PowerPC assembly code. The idea behind aRISC architecture is that the compiler can do a better job than you, andthat you should leave assembly up to the compiler. Assembly codedefinitely makes it harder to port your application (even though thereare only two Macintosh platforms right now). Instead of writing inassembly you should program in C. This not being a perfect world,that's not always as easy as it sounds. Assembly is needed to storevalues in specific registers. This amount of control isn't available inC. TechInfo has this problem. As stated above, TechInfo passes
AsmClikLoopas its ClickLoop procedure. The reasonTechInfo uses assembly is that TextEdit expects the ClickLoop procedureto put a 1 in register D0. When you are compiling for the PPC, you haveto use a UPP for the ClickLoop. A UPP contains the calling conventionfor a procedure, including where the result of the procedure should bestored. Consequently assembly code isn't needed because the Mixed ModeManager will do the right thing.
Code ResourcesTo create a code resource, set the project type to 'Code Resources' inthe 'Project' panel of the preferences. You also have to select 'ExpandUninitialized Data' in the 'PEF' panel. In the 'Linker' panel, set the'Main' entry point to 'main.'
Code resources are another case when you don't know if your code isbeing run on a 68K machine or a PPC one. You could just provide a 68Kcode resource, but then it wouldn't run at blazing speeds on aPower Mac. To get both version in one package you need to make a safecode resource. A safe code resource has code to detect which kind ofmachine the code resource is being executed on and runs the correctversion. CodeWarrior 5 can't make safe code resources, but laterversions should. Until they do you'll have to go through thecontortions described here.
TechInfo puts all of its code resources into one file. The 68K versionof its CDEF is resource type 'CDFm' and its PPC version is type 'CDFp'.There is a resource template in MixedMode.r (one of Rez's headers) for aresource type 'sdes', a safe code resource. The 'sdes' templatecontains the code for checking the platform and calling the rightversion of the code resource. This is part of the .r file that TechInfouses to create a safe CDEF:The first two numbers are procedure information for the code resource.Use the ProcInfo project in the CodeWarrior Examples folder to determinethe correct value for this field. Then comes the 68K and PPC versions.This code needs to be compiled with Rez, which will create the safe coderesource.
Fat BinariesNow that you have a 68K version of your program, a PPC version of yourprogram, and fat code resources, you probably want to merge them intoone and create a fat binary. A fat binary will run native on either a68K Macintosh or a Power Macintosh because it has both versions ofthe program. 68K applications don't use the data fork. All of the codeis stored in 'CODE' resources. PPC code, which is handled by the CodeFragment Manager, can be stored in either the data or the resource fork.PPC applications are stored in the data fork. To make a fat binary allyou have to do is put the PPC program in the data fork, the 68K code inthe resource fork, and the program's resources in the resource fork.Both versions of the program will share the same set of applicationresources.
CodeWarrior makes it easy to create fat binaries. You can include the68K application and the application resources in the PPC version'sproject. When CodeWarrior links the PPC version it will copy theresources from the application and resource files, creating a fatbinary.
References and Further ReadingMacintosh on RISC SDK has a checklist for porting code to thePower Macintosh.
For information on the PowerPC architecture, the Mixed Mode Manager, theCode Fragment Manager, UniversalProcPtrs, and more, see:
'Making the Leap to PowerPC,' by Dave Radcliffe, developIssue 16.
InsideMacintosh: PowerPCSystem Software by Apple Computer, Inc. (Addison-Wesley, 1994).
For information on standalone code and fat resources see:
'Standalone Code on PowerPC,' by Tim Nichols, developIssue 17.
To learn how to speed up your Power Mac code see
'Exploiting Graphics Speed on the Power Macintosh,' by KonstantinOthmer, Shannon Holland, and Brian Cox, developIssue 18.
'Balance of Power: Enhancing PowerPC Native Speed,' by Dave Evans, developIssue 18.
And other 'Balance of Power' columns in developIssue 19, developIssue 20, and developIssue 21 on memory usage, branch prediction, and PPC assembly.
For information on a wide variety of topics concerning the PowerPC, seethe PowerPC feature of MacTech Magazinefrom February 1994 until at least September 1994.
The source forthe entire TechInfo project, including project files and source codemay serve as an example of what was talked about in this document. Youmay also want to read about building TechInfoto see how the fat version of TechInfo is created
Of course, to learn about the real guts of the PowerPC see the PowerPCTechnical Library.
Questions or comments? Send mail to [email protected]
Last updated on $Date: 2003/11/18 21:58:17 $
Last modified by $Author: smcguire $
CodeWarrior for Mac OS, Professional Edition
Industry’s #1 Professional Development Tool Suite
Coming May 31, 2002
Only CodeWarrior Development Tools for Mac OS, v8 unleashes your
imagination to develop applications faster and easier with the true
flexibility you need to speed your time to market.
The CodeWarrior tools for Mac OS include a feature-rich integrated
development environment (IDE) that enables you to build applications for
both Mac OS X and Classic Mac OS. And, you can choose from two
object-oriented class libraries: Metrowerks PowerPlant or Apple’s Cocoa. In
fact, you can use this powerful CodeWarrior tool suite to build any code
based on C, C++, Objective-C, or Java.
The CodeWarrior IDE has everything you need in one easy-to-use tool suite:
an advanced project manager, build system, source code editor, code
completion for C, C+ + and Java, compilers, linkers, debuggers, class
browser, and more. Best of all, CodeWarrior tools for Mac OS, v8 is from
Metrowerks, the choice of serious application developers around the world.
CodeWarrior Development Tool suite for Mac OS, v8 enables you to build:
=B7 Carbon-based applications for Classic Mac OS and Mac OS X
=B7 PowerPlant applications for Classic Mac OS and Mac OS X
=B7 Cocoa applications for Mac OS X
=B7 Java applets, applications and beans for Classic Mac OS and Mac OS X
=B7 Classic Mac OS applications
Code Completion for C, C ++, and Java- Write code faster without the need
to look up hard-to-remember functions and symbols, using the code
PowerPlant, the most powerful C++ Framework for Mac OS- Save time and
effort by leveraging Metrowerks PowerPlant C++ class library that provides
standard services and infrastructure for all Mac OS X and Classic Mac OS
Cocoa Framework and Interface Builder- Quickly design and build the user
interface for your Cocoa and Carbon applications. Apple Interface Builder
and the CodeWarrior IDE work hand-in-hand.
Codewarrior Predefined Macros
New Mach-O Linker- The CodeWarrior linker built from the ground up
completely supports Mach-O for improved speed, smaller executables, and
better debugging support.
Automatic Package Management- The CodeWarrior IDE has automated the process
of application packaging so your able to quickly and easily organize your
Mac OS X bundles.
Java RAD Tools- Write less code, build easier-to-use software, and complete
your projects faster with our Java Rapid Applications Tools.
Cross-Platform Development- Build applications for both Mac OS and Windows
within one development environment. CodeWarrior tools for cross-platform
development minimizes code changes between platforms and supports multiple
development environments on a single platform.
Class Browser- Instantly look up the definition or implementation of any
symbol in your project using the CodeWarrior Class Browser.
Multimedia and Programming Tutorials- CodeWarrior tools for Mac OS
tutorials provide easy-to-follow instructions on how to use the CodeWarrior
IDE and how to program in C, C+ +, and Java.